python - true - valores booleanos y operaciones logicas
El operador de Python en(__contains__) devuelve un bool cuyo valor no es True ni False (1)
Como se esperaba, 1 no está contenido por la tupla vacía
>>> 1 in ()
False
pero el valor False
devuelto no es igual a False
>>> 1 in () == False
False
Mirándolo de otra manera, el operador in
devuelve un bool
que no es ni True
ni False
:
>>> type(1 in ())
<type ''bool''>
>>> 1 in () == True, 1 in () == False
(False, False)
Sin embargo, el comportamiento normal se reanuda si la expresión original está entre paréntesis
>>> (1 in ()) == False
True
o su valor se almacena en una variable
>>> value = 1 in ()
>>> value == False
True
Este comportamiento se observa tanto en Python 2 como en Python 3.
¿Puedes explicar lo que está pasando?
Te estás enfrentando al encadenamiento de operadores de comparación; 1 in () == False
no significa (1 in ()) == False
.
Por el contrario, las comparaciones están encadenadas y la expresión realmente significa:
(1 in ()) and (() == False)
Como (1 in ())
ya es falso, la segunda mitad de la expresión encadenada se ignora por completo (ya que False and something_else
devuelven False
cualquiera que sea el valor de something_else
).
Ver la documentación de expresiones de comparaciones :
Las comparaciones se pueden encadenar arbitrariamente, por ejemplo,
x < y <= z
es equivalente ax < y and y <= z
, excepto quey
se evalúa solo una vez (pero en ambos casosz
no se evalúa cuandox < y
se encuentra ser falso).
Para el registro, <
, >
, ==
, >=
, <=
, !=
, is not
, in
y not in
son todos los operadores de comparación (como lo es el <>
).
En general, no compare contra booleanos; simplemente prueba la expresión en sí misma. Si tiene que probar contra un literal booleano, al menos use paréntesis y el operador is
, True
y False
son singletons, como None
:
>>> (1 in ()) is False
True
Esto se vuelve aún más confuso cuando los enteros están involucrados. El tipo de bool
Python es una subclase de int
1 . Como tal, False == 0
es verdadero, como es True == 1
. Por lo tanto, puede concebir operaciones encadenadas que casi parecen cuerdas:
3 > 1 == True
es verdadero porque 3 > 1
y 1 == True
son ambos verdaderos. Pero la expresión:
3 > 2 == True
es falso, porque 2 == True
es falso.
1 bool
es una subclase de int
por razones históricas; Python no siempre tenía un tipo bool
y enteros sobrecargados con un significado booleano como C lo hace. Al hacer que bool
una subclase, el código anterior funcionaba.