Con lo fácil que debería ser comparar variables para saber si su valor es True o False 😩😩😩😩 Sí, en un principio es una acción de lo más simple pero por el modo en que está implementado Python veremos cuáles son las recomendaciones por parte del lenguaje y las incógnitas ocultas.
Cómo comparar variables de forma correcta
Antes de explicar la forma correcta de comparar variables, voy a repasar lo que seguramente much@s de vosotr@s habéis visto y/o usado:
Comparar variables con ==
Sí, si vienes de otros lenguajes quizá uses o hayas usado lo siguiente para comparar variables:
if foo == True: # Código si foo es True
Comparar variables con is
La versatilidad de Python hace que en muchas ocasiones el código funcione aunque no sea correcto o creamos que está haciendo una cosa cuando en realidad hace otra muy distinta. Es lo que ocurre si usas el operador is
para comprobar si el valor de una variable es True
o False
.
if foo is True: # ¿Código si foo es True?
No entiendo. ¿Cuál es la forma correcta de comparar variables?
Pues en Python ocurre muchas veces que lo más simple es lo mejor. Siguiendo esta norma, la forma correcta de comparar si el valor de una variable es True
o False
es la siguiente:
if foo: # foo es True else: # foo es False if not foo: # foo es False else: # foo es True
De hecho, es la forma recomendada por el propio lenguaje.
En la siguiente sección intentaré mostrarte el por qué.
Entendiendo cómo evalúa Python las variables
- En Python, los valores «vacíos» son evaluados como
False
. Estos valores sonNone
,0
,0.0
,""
yFalse
. - Los tipos «contenedor» como
list
,dict
,str
,tuple
, etc. son evaluados comoFalse
si no contienen elementos. - Cualquier otro valor es evaluado como
True
. - El operador
is
compara la identidad de dos objetos. Se evalúa aTrue
si los operandos apuntan al mismo objeto - El operador
==
compara los valores de dos objetos.
Todo esto puede resultar un poco complejo, así que lo mejor es verlo con un ejemplo:
>>> var_none = None >>> var_cero = 0 >>> lista_vacia = [] >>> var_false = False >>> var_uno = 1 >>> var_menos_uno = -1.1 >>> var_true = True >>> lista_con_elem = [1, 2] >>> if var_none: ... print('var_none es True') ... else: ... print('var_none es False') var_none es False >>> if var_cero: ... print('var_cero es True') ... else: ... print('var_cero es False') var_cero es False >>> if lista_vacia: ... print('lista_vacia es True') ... else: ... print('lista_vacia es False') lista_vacia es False >>> if var_false: ... print('var_false es True') ... else: ... print('var_false es False') var_false es False >>> if var_uno: ... print('var_uno es True') ... else: ... print('var_uno es False') var_uno es True >>> if var_menos_uno: ... print('var_menos_uno es True') ... else: ... print('var_menos_uno es False') var_menos_uno es True >>> if var_true: ... print('var_true es True') ... else: ... print('var_true es False') var_true es True >>> if lista_con_elem: ... print('lista_con_elem es True') ... else: ... print('lista_con_elem es False') lista_con_elem es True
Hasta aquí lo sencillo. Ahora veremos por qué no comparar con is
o ==
cuando lo que queremos evaluar es si el valor de una variable es True
o False
.
var_cero is True False var_cero is False False var_cero == True False var_cero == False True
Como vemos var_cero
es una variable de tipo int
, luego el operador is
nunca puede devolver True
porque los operandos hacen referencia a objetos distintos. Cuando se compara con el operador ==
y el valor False
, el resultado es True
por la implementación de CPython.
>>> var_none == False False >>> var_none == True False >>> var_none is False False >>> var_none is True False
En esta ocasión todas las comparaciones devuelven False
porque el objeto None
(sí, en Python None
es un objeto que representa la ausencia de valor) es diferente a True
y False
.
A continuación te dejo el resto de ejemplos para que los evalúes:
>>> lista_vacia == False False >>> lista_vacia == True False >>> lista_vacia is False False >>> lista_vacia is True False >>> var_uno == False False >>> var_uno == True True >>> var_uno is False False >>> var_uno is True False
Todo resumido
- Si lo que quieres es saber si una variable
foo
NO tiene asignado un valor no vacío (recuerda:None
,0
,0.0
,""
oFalse
), puedes usar simplemente el nombre de la variableif foo:
o para el caso contrarioif not foo:
. - Si una variable
foo
puede tener el valorNone
, entonces compara si tiene valor conif foo is None
oif foo is not None:
. - Si quieres saber si una variable de tipo contenedor
foo
tiene elementos, usa directamente la variableif foo:
. En este casoif not foo:
puede serTrue
si la variable no contiene elementos o su valor esNone
. ❗️Cuidado con esto. - Si lo que quieres saber es si una variable
foo
es de tipobooleano
y su valor esFalse
, entonces usa la siguiente expresión:if not foo and isinstance(foo, bool):
. - Usa el operador
==
para comparar el valor de dos variables.