Comparar cadenas en Python: __eq__()
, no igual, algoritmo, complejidad temporal, ignorar mayúsculas y minúsculas, comparación de listas
Este post resume las preguntas más frecuentes sobre la comparación de cadenas en Python.
1. El método __eq__(
)
El método __eq__()
es uno de los métodos especiales en Python usados para comparar dos objetos para ver si son iguales.
Este método es llamado por sí mismo cuando se comparan dos objetos con el operador ==
.
Las operaciones de comparación de cadenas de Python también llaman a este método porque usan el operador ==
.
Esto significa que cuando ejecutas "Hola" == "hola"
, Python en realidad está llamando internamente a "Hola".__eq__("hola")
.
Si lo ejecutas como el código anterior, obtendrás el resultado de que las dos cadenas son diferentes
str1 = 'Hola'
str2 = 'hola'
print(str1 == str2) # output: False
Esto se debe a que el método __eq__()
definido dentro de str
, la clase incorporada que representa cadenas en Python, distingue entre mayúsculas y minúsculas.
Por lo tanto, podemos decir que cualquier clase incorporada de Python que utilice el operador ==
tiene el método __eq__()
definido dentro de su clase.
Podemos personalizar el comportamiento del operador ==
anulando el método __eq__()
de cualquier clase.
Si este método no existe, Python compara por defecto las direcciones de memoria de los dos objetos.
El siguiente ejemplo define una nueva clase de cadenas CaseInsensitiveStr
que realiza comparaciones sin distinción entre mayúsculas y minúsculas.
Observe cómo se define el método __eq__()
.
class CaseInsensitiveStr:
def __init__(self, str_):
self.str_ = str_.lower()
def __eq__(self, other):
if isinstance(other, CaseInsensitiveStr):
return self.str_ == other.str_
elif isinstance(other, str):
return self.str_ == other.lower()
return False
str1 = CaseInsensitiveStr('Hola')
str2 = CaseInsensitiveStr('hola')
print(str1 == str2) # output: True
2. usando not-equal (>
,<
)
Al comparar cadenas en Python, los operadores not-equal se pueden utilizar para dos propósitos
- Indicar orden lexicográfico
- Indicar una relación de inclusión
2.1. Operadores no-iguales para indicar el orden lexicográfico
Empecemos por el primero: Python se basa en valores ASCII para las comparaciones alfanuméricas y en valores Unicode (principalmente utf-8
) para los caracteres coreanos.
Cuando comparas los alfabetos a
y b
de esta forma, en realidad estás comparando los valores ASCII de estos dos caracteres.
La función ord()
es una función incorporada que devuelve el punto de código Unicode (incluido el código ASCII) de un carácter dado, por lo que puede obtener el valor numérico de cualquier carácter.
print("a" == "b") # this comparison is actually
print(ord("a") == ord("a")) # This comparison is true.
Por el mismo principio, cuando se utilizan operadores no iguales como >
y <
para comparar cadenas, se están comparando los valores de los puntos de código Unicode.
Estos valores se escalan alfabéticamente tanto para caracteres alfabéticos como alfanuméricos. Por ejemplo, z
es mayor que a
, las minúsculas son mayores que las mayúsculas.
print("a" < "z") # Output: True
print("A" < "a") # Output: True
2.2. Operadores no iguales para representar relaciones de inclusión
El segundo uso es para las relaciones de inclusión entre cadenas.
Cuando Python compara cadenas de dos o más caracteres, las compara una a una, empezando por el elemento más antiguo. Si una cadena es una subcadena de otra, en algún momento tendrá que comparar caracteres y espacios. En ese momento, se determina que la cadena más larga es mayor.
Veamos esto en código
print("árboles" > "árbol") Output: True
Dado que "árbol"
es una subcadena de "árboles"
, siempre se resolverá como el valor más pequeño.
Menciono esto no para sugerir que deberías usar operadores no-iguales en relaciones de contención de cadenas,
sino para ilustrar cómo funciona la comparación de cadenas en Python.
Tenemos la poderosa palabra clave in
para determinar la inclusión.
3. Algoritmo de comparación de cadenas de Python y complejidad temporal
El algoritmo de comparación de cadenas de Python es intuitivo. Para comparar dos cadenas, Python compara los dos primeros caracteres en el mismo índice.
Esto resulta en una complejidad temporal de O(n)
cuando se requiere el máximo número de operaciones, como "hola" == "holu"
.
4.Cómo ignorar mayúsculas y minúsculas al comparar dos cadenas
Como se mencionó en la Sección 1, la clase str
de Python implementa el método __eq__()
que distingue entre mayúsculas y minúsculas.
Si quieres comparar dos cadenas sin distinguir mayúsculas de minúsculas, puedes usar los métodos upper()
o lower()
de la clase str
.
Como su nombre indica, el método upper()
pone en mayúsculas todos los caracteres de una cadena dada,
El método lower()
devuelve una nueva cadena con los caracteres de la cadena dada convertidos a minúsculas.
Debido a esto, es fácil ignorar mayúsculas y minúsculas y hacer comparaciones.
Veamos esto en un ejemplo de código
lower_case = "happy"
mixed_case = "HaPPy"
print(lower_case == mixed_case) # output: False
print(lower_case.upper() == mixed_case.upper()) # output: True
Así es como se obtiene el resultado de la comparación de cadenas de Python insensible a mayúsculas y minúsculas.
5. Comparación Cadena-Lista
Las cadenas y las listas de Python son tipos de datos diferentes, por lo que compararlas directamente siempre devolverá False
.
print(["a", "b", "c"] == "abc") # Output: False
Para comparar el contenido de dos tipos de datos, tenemos que hacer coincidir los tipos de datos. Para ello, podemos utilizar los dos métodos siguientes.
5.1. Función list() para convertir una cadena en una lista
El primer método convierte una cadena en una lista. La función list()
de Python es una función sencilla que convierte muchos tipos de datos diferentes en listas.
Utilízala así
print(list("abc")) # Output: ["a", "b", "c"]
print(["a", "b", "c"] == list("abc")) # output: True
Como los tipos de datos son iguales, comparamos los elementos de las dos listas y devolvemos un valor True
.
5.2. Método join() para convertir listas en cadenas
Alternativamente, podemos convertir las listas en cadenas y luego compararlas.
Para ello, utiliza el método join()
. Este método combina todos los elementos de la lista en una sola cadena.
print("".join(["a", "b", "c"])) # output: "abc"
print("".join(["a", "b", "c"]) == "abc") # Output: True
Ahora que tenemos el mismo tipo de cadena, podemos comparar el contenido.
6. Conclusión
Hemos cubierto 5 de las preguntas más frecuentes sobre la comparación de cadenas en Python, y espero que este post haya aclarado algunas de tus dudas.
