¿Por qué "no (Verdadero) en [Falso, Verdadero]" devuelve Falso?
Si hago esto:
>>> False in [False, True]
True
Eso regresa True
. Simplemente porque False
está en la lista.
Pero si lo hago:
>>> not(True) in [False, True]
False
Eso regresa False
. Mientras que not(True)
es igual a False
:
>>> not(True)
False
¿Por qué?
Prioridad del operador 2.x , 3.x. La precedencia de not
es menor que la de in
. Entonces es equivalente a:
>>> not ((True) in [False, True])
False
Esto es lo que quieres:
>>> (not True) in [False, True]
True
Como señala @Ben: Se recomienda no escribir nunca not(True)
, prefiero not True
. El primero hace que parezca una llamada a función, mientras que not
es un operador, no una función.
not x in y
se evalúa comox not in y
Puedes ver exactamente lo que está sucediendo desensamblando el código. El primer caso funciona como se esperaba:
>>> x = lambda: False in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (False)
3 LOAD_GLOBAL 0 (False)
6 LOAD_GLOBAL 1 (True)
9 BUILD_LIST 2
12 COMPARE_OP 6 (in)
15 RETURN_VALUE
El segundo caso, se evalúa como True not in [False, True]
, que es False
claramente:
>>> x = lambda: not(True) in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (True)
3 LOAD_GLOBAL 1 (False)
6 LOAD_GLOBAL 0 (True)
9 BUILD_LIST 2
12 COMPARE_OP 7 (not in)
15 RETURN_VALUE
>>>
En cambio, lo que quería expresar era (not(True)) in [False, True]
, que como se esperaba es True
, y puede ver por qué:
>>> x = lambda: (not(True)) in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (True)
3 UNARY_NOT
4 LOAD_GLOBAL 1 (False)
7 LOAD_GLOBAL 0 (True)
10 BUILD_LIST 2
13 COMPARE_OP 6 (in)
16 RETURN_VALUE
Precedencia de operadores. in
se une más estrechamente que not
, por lo que su expresión es equivalente a not((True) in [False, True])
.