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 <= zes equivalente ax < y and y <= z, excepto queyse evalúa solo una vez (pero en ambos casoszno se evalúa cuandox < yse 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.