Comparando cadenas usando Python

    En Python, las cadenas son secuencias de caracteres, que se almacenan efectivamente en la memoria como un objeto. Cada objeto se puede identificar mediante el id() m茅todo, como puede ver a continuaci贸n. Python intenta reutilizar objetos en la memoria que tienen el mismo valor, lo que tambi茅n hace que la comparaci贸n de objetos sea muy r谩pida en Python:

    $ python
    Python 2.7.9 (default, Jun 29 2016, 13:08:31)
    [GCC 4.9.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> a = "abc"
    >>> b = "abc"
    >>> c = "def"
    >>> print (id(a), id(b), id(c))
    (139949123041320, 139949123041320, 139949122390576)
    >>> quit()
    

    Para comparar cadenas, Python ofrece algunos operadores diferentes para hacerlo. Primero, los explicaremos con m谩s detalle a continuaci贸n. En segundo lugar, repasaremos tanto string y el re m贸dulos, que contienen m茅todos para manejar coincidencias inexactas y sin distinci贸n entre may煤sculas y min煤sculas. En tercer lugar, para tratar con cadenas de varias l铆neas, m贸dulo difflib es bastante 煤til. Varios ejemplos le ayudar谩n a comprender c贸mo utilizarlos.

    Los operadores == y! =

    Como operador de comparaci贸n b谩sico, querr谩 usar == y !=. Funcionan exactamente de la misma manera que con valores enteros y flotantes. los == el operador regresa True si hay una coincidencia exacta, de lo contrario False Ser谩 devuelto. En contraste, el != devoluciones del operador True si no hay coincidencia y de lo contrario regresa False. El Listado 1 demuestra esto.

    en un for loop, una cadena que contiene el nombre de la ciudad suiza “Lausanne” se compara con una entrada de una lista de otros lugares, y el resultado de la comparaci贸n se imprime en stdout.

    Listado 1:

    # define strings
    listOfPlaces = ["Berlin", "Paris", "Lausanne"]
    currentCity = "Lausanne"
    
    for place in listOfPlaces:
        print ("comparing %s with %s: %s" % (place, currentCity, place == currentCity))
    

    Ejecutando el script de Python desde arriba, el resultado es el siguiente:

    $ python3 comparing-strings.py
    comparing Berlin with Lausanne: False
    comparing Paris with Lausanne: False
    comparing Lausanne with Lausanne: True
    

    los == y is Operadores

    Python tiene los dos operadores de comparaci贸n == y is. A primera vista parecen ser iguales, pero en realidad no lo son. == compara dos variables en funci贸n de su valor real. En contraste, el is el operador compara dos variables basadas en la identificaci贸n del objeto y devuelve True si las dos variables se refieren al mismo objeto.

    El siguiente ejemplo demuestra eso para tres variables con valores enteros. Las dos variables a y b tienen el mismo valor y Python se refiere al mismo objeto para minimizar el uso de memoria.

    >>> a = 1
    >>> b = 1
    >>> c = 2
    >>> a is b
    True
    >>> a is c
    False
    >>> id(a)
    10771520
    >>> id(b)
    10771520
    

    Tan pronto como el valor cambie, Python reinstalar谩 el objeto y asignar谩 la variable. En el siguiente fragmento de c贸digo b obtiene el valor de 2, y posteriormente b y c se refieren al mismo objeto.

    >>> b = 2
    >>> id(b)
    10771552
    >>> id(c)
    10771552
    

    Una regla general a seguir es utilizar == al comparar tipos inmutables (como ints) y is al comparar objetos.

    M谩s operadores de comparaci贸n

    Para una comparaci贸n con respecto a un orden lexicogr谩fico, puede utilizar los operadores de comparaci贸n <, >, <=y >=. La comparaci贸n en s铆 se hace car谩cter por car谩cter. El orden depende del orden de los caracteres en el alfabeto. Este orden depende de la tabla de caracteres que est茅 en uso en su m谩quina mientras se ejecuta el c贸digo Python.

    Tenga en cuenta que el orden distingue entre may煤sculas y min煤sculas. Como ejemplo del alfabeto latino, “Bus” viene antes de “bus”. El Listado 2 muestra c贸mo funcionan estos operadores de comparaci贸n en la pr谩ctica.

    Listado 2:

    # define the strings
    listOfPlaces = ["Berlin", "Paris", "Lausanne"]
    currentCity = "Lausanne"
    
    for place in listOfPlaces:
        if place < currentCity:
                print ("%s comes before %s" % (place, currentCity))
        elif place > currentCity:
                print ("%s comes after %s" % (place, currentCity))
        else:
                print ("%s is similar to %s" % (place, currentCity))
    

    Al ejecutar el script de Python desde arriba, la salida es la siguiente:

    $ python3 comparing-strings-order.py
    Berlin comes before Lausanne
    Paris comes after Lausanne
    Lausanne is similar to Lausanne
    

    Comparaciones que no distinguen entre may煤sculas y min煤sculas

    Los ejemplos anteriores se centraron en coincidencias exactas entre cadenas. Para permitir comparaciones que no distinguen entre may煤sculas y min煤sculas, Python ofrece m茅todos de cadena especiales como upper() y lower(). Ambos est谩n disponibles directamente como m茅todos del objeto de cadena correspondiente.

    upper() convierte toda la cadena en letras may煤sculas, y lower() en letras min煤sculas, respectivamente. Basado en el Listado 1, el siguiente listado muestra c贸mo usar el lower() m茅todo.

    Listado 3:

    # using the == operator
    listOfPlaces = ["Berlin", "Paris", "Lausanne"]
    currentCity = "lausANne"
    
    for place in listOfPlaces:
        print ("comparing %s with %s: %s" % (place, currentCity, place.lower() == currentCity.lower()))
    

    El resultado es el siguiente:

    $ python3 comparing-strings-case-insensitive.py
    comparing Berlin with lausANne: False
    comparing Paris with lausANne: False
    comparing Lausanne with lausANne: True
    

    Usar una expresi贸n regular

    Una expresi贸n regular, o “regex” para abreviar, define un patr贸n espec铆fico de caracteres. Respecto a este tema, Jeffrey Friedl escribi贸 un excelente libro titulado Dominar las expresiones regulares, que recomiendo encarecidamente.

    Para hacer uso de este mecanismo en Python, importe el re m贸dulo primero y definir un patr贸n espec铆fico, a continuaci贸n. Nuevamente, el siguiente ejemplo se basa en el Listado 1. El patr贸n de b煤squeda coincide con “bah铆a” y comienza con una letra min煤scula o may煤scula. Precisamente, el siguiente c贸digo de Python encuentra todas las cadenas en las que se produce el patr贸n de b煤squeda sin importar en qu茅 posici贸n de la cadena: al principio, en el medio o al final.

    Listado 4:

    # import the additional module
    import re
    
    # define list of places
    listOfPlaces = ["Bayswater", "Table Bay", "Bejing", "Bombay"]
    
    # define search string
    pattern = re.compile("[Bb]ay")
    
    for place in listOfPlaces:
        if pattern.search(place):
            print ("%s matches the search pattern" % place)
    

    El resultado es el siguiente y coincide con “Bayswater”, “Table Bay” y “Bombay” de la lista de lugares:

    $ python3 comparing-strings-re.py
    Bayswater matches the search pattern
    Table Bay matches the search pattern
    Bombay matches the search pattern
    

    Comparaciones de listas y l铆neas m煤ltiples

    Hasta ahora, nuestras comparaciones se han basado en unas pocas palabras. Utilizando el difflib El m贸dulo Python tambi茅n ofrece una forma de comparar cadenas de varias l铆neas y listas completas de palabras. La salida se puede configurar de acuerdo con varios formatos de herramientas de diferencias.

    El siguiente ejemplo (Listado 5) compara dos cadenas de varias l铆neas l铆nea por l铆nea y muestra tanto las eliminaciones como las adiciones. Despu茅s de la inicializaci贸n del Differ objeto en la l铆nea 12 la comparaci贸n se realiza utilizando el compare() m茅todo en la l铆nea 15. El resultado se imprime en stdout (l铆nea 18).

    Listado 5:

    # import the additional module
    import difflib
     
    # define original text
    # taken from: https://en.wikipedia.org/wiki/Internet_Information_Services
    original = ["About the IIS", "", "IIS 8.5 has several improvements related", "to performance in large-scale scenarios, such", "as those used by commercial hosting providers and Microsoft's", "own cloud offerings."]
    
    # define modified text
    edited = ["About the IIS", "", "It has several improvements related", "to performance in large-scale scenarios."]
    
    # initiate the Differ object
    d = difflib.Differ()
     
    # calculate the difference between the two texts
    diff = d.compare(original, edited)
     
    # output the result
    print ('n'.join(diff))
    

    La ejecuci贸n del script crea la salida como se ve a continuaci贸n. Las l铆neas con supresiones se indican mediante - signos mientras que las l铆neas con adiciones comienzan con un + firmar. Adem谩s, las l铆neas con cambios comienzan con un signo de interrogaci贸n. Los cambios se indican mediante ^ Se帽ales en la posici贸n correspondiente. Las l铆neas sin indicador siguen siendo las mismas.

    $ python comparing-strings-difflib.py
      About the IIS
      
    - IIS 8.5 has several improvements related
    ?  ^^^^^^
    
    + It has several improvements related
    ?  ^
    
    - to performance in large-scale scenarios, such
    ?                                        ^^^^^^
    
    + to performance in large-scale scenarios.
    ?                                        ^
    
    - as those used by commercial hosting providers and Microsoft's
    - own cloud offerings.
    

    Conclusi贸n

    En este art铆culo, ha aprendido varias formas de comparar cadenas en Python. Esperamos que esta descripci贸n general lo ayude a programar de manera efectiva en la vida de su desarrollador.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *