¿Por qué" no(Verdadero) en [Falso, Verdadero] " devuelve Falso?


Si hago esto:

>>> False in [False, True]
True

Que devuelve True. Simplemente porque False está en la lista.

Pero si lo hago:

>>> not(True) in [False, True]
False

Que devuelve False. Considerando que {[6] } es igual a False:

>>> not(True)
False

¿Por qué?

Author: Benjamin Hodgson, 2015-07-15

8 answers

Precedencia del operador 2.x, 3.x. La precedencia de not es menor que la de in. Así que 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 nunca escribir not(True), prefiera not True. El primero hace que parezca una llamada a una función, mientras que not es un operador, no una función.

 708
Author: Yu Hao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-22 01:13:46

not x in y se evalúa como x not in y

Puedes ver exactamente lo que está sucediendo desensamblando el código. El primer caso funciona como se espera:

>>> 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, evalúa a 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        
>>> 

Lo que querías expresar en su lugar era (not(True)) in [False, True], que como se esperaba es True, y puedes 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        
 72
Author: Roshan Mathews,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 04:39:48

Precedencia del operador. in se une más firmemente que not, por lo que su expresión es equivalente a not((True) in [False, True]).

 35
Author: mooiamaduck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 04:17:14

Todo se trata de precedencia del operador (in es más fuerte que not). Pero se puede corregir fácilmente agregando paréntesis en el lugar correcto:

(not(True)) in [False, True]  # prints true

Escrito:

not(True) in [False, True]

Es lo mismo que:

not((True) in [False, True])

Que busca si True está en la lista y devuelve el "not" del resultado.

 33
Author: alfasin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-16 01:12:16

Se evalúa como not True in [False, True], que devuelve False porque True está en [False, True]

Si lo intentas

>>>(not(True)) in [False, True]
True

Se obtiene el resultado esperado.

 14
Author: user3636636,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 04:18:32

Junto con las otras respuestas que mencionan la precedencia de not es menor que in, en realidad su declaración es equivalente a:

not (True in [False, True])

Pero tenga en cuenta que si no separa su condición de las otras, python usará 2 roles (precedence o chaining) para separar eso, y en este caso python usó precedencia. Además, tenga en cuenta que si desea separar una condición, debe poner toda la condición entre paréntesis, no solo el objeto o valor :

(not True) in [False, True]

Pero como se mencionó, hay otra modificación de python en los operadores que es encadenamiento :

Basado en python documentación :

Tenga en cuenta que las comparaciones, las pruebas de pertenencia y las pruebas de identidad, todas tienen la misma precedencia y tienen una característica de encadenamiento de izquierda a derecha como se describe en la sección Comparaciones.

Por ejemplo, el resultado de la siguiente declaración es False:

>>> True == False in [False, True]
False

Porque python encadenará las sentencias como sigue:

(True == False) and (False in [False, True])

Que es exactamente False and True que es False.

Se puede asumir que el objeto central será compartido entre 2 operaciones y otros objetos (False en este caso).

Y tenga en cuenta que también es cierto para todas las comparaciones, incluidas las pruebas de membresía y las operaciones de pruebas de identidad que son los siguientes operandos:

in, not in, is, is not, <, <=, >, >=, !=, ==

Ejemplo:

>>> 1 in [1,2] == True
False

Otro ejemplo famoso es rango de números:

7<x<20

Que es igual a:

7<x and x<20   
 13
Author: Kasrâmvd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-01 14:43:09

Vamos a verlo como una operación de comprobación de contención de colección: [False, True] es una lista que contiene algunos elementos.

La expresión True in [False, True] devuelve True, ya que True es un elemento contenido en la lista.

Por lo tanto, not True in [False, True] da el "opuesto booleano", not resultado de la expresión anterior (sin ningún paréntesis para preservar la precedencia, ya que in tiene mayor precedencia que el operador not). Por lo tanto, not True resultará False.

Por otro lado, (not True) in [False, True], es igual a False in [False, True], que es True (False figura en la lista).

 6
Author: Nick Louloudakis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 19:05:01

Para aclarar algunas de las otras respuestas, agregar paréntesis después de un operador unario no cambia su precedencia. not(True) no hace que not se ate más firmemente a True. Es solo un conjunto redundante de paréntesis alrededor de True. Es lo mismo que (True) in [True, False]. Los paréntesis no hacen nada. Si desea que el enlace sea más apretado, debe poner los paréntesis alrededor de toda la expresión, lo que significa tanto el operador como el operando, es decir, (not True) in [True, False].

Para ver esto otra manera, considere

>>> -2**2
-4

** se une más firmemente que -, por lo que se obtiene el negativo de dos al cuadrado, no el cuadrado de dos negativos (que sería cuatro positivos).

¿Y si quisieras el cuadrado de dos negativos? Obviamente, añadirías paréntesis:

>>> (-2)**2
4

Sin embargo, no es razonable esperar que lo siguiente dé 4

>>> -(2)**2
-4

Porque -(2) es lo mismo que -2. Los paréntesis no hacen absolutamente nada. {[3] } es exactamente el igual.

 6
Author: asmeurer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-19 00:12:43