python - how to change font size matplotlib
¿Por qué ''None is None None None'' devuelve True? (3)
Esta pregunta ya tiene una respuesta aquí:
Hoy, en una entrevista, el CTO me preguntó qué parece una pregunta fácil,
¿Qué devuelve esta declaración? :
None is None is None
Pensé que Python ejecutó la primera operación
None is None
y devolvería
True
.
Después de eso, compararía
True is None
que devolvería
False
.
Pero, para mi sorpresa, la respuesta correcta es la
True
.
Estoy tratando de encontrar una respuesta a esta pregunta, pero después de un par de días buscando no encontré nada.
¿Alguien puede explicar por qué sucede esto?
Como algunos comentan, las comparaciones de Python se pueden encadenar .
Por el bien de la explicación, cuando se encadena, Python en realidad son las expresiones.
La
razón detrás de esto
, es que expresiones como
a < b < c
tienen la interpretación que es convencional en matemáticas.
Por lo tanto, la confusión de su expresión en particular,
None is None is None
en la que
participan
operadores de
identidad
.
Así que básicamente, esto se traduciría a:
(None is None) and (None is None)
que es claramente
True
Aquí hay otro ejemplo en la docs Python.
Más información
Especialmente debido a que esta fue una pregunta de entrevista, es importante tener en cuenta que este no es un comportamiento general compartido entre todos los idiomas.
Como se indica en la documentación que vinculé,
A diferencia de C, todas las operaciones de comparación en Python tienen la misma prioridad, que es menor que la de cualquier operación aritmética, de desplazamiento o de bit a bit.
Entonces, consideremos la expresión
10 > x > 2
(ya que
is
operador no es válido en C).
Traducción de C (debido a la precedencia del operador )
((10 > x) > 2)
Traducción de Python
(10 > x) and (x > 2)
El bytecode muestra que se están realizando dos comparaciones aquí con el medio duplicado:
>>> import dis
>>> def a():
... return None is None is None
...
>>> dis.dis(a)
2 0 LOAD_CONST 0 (None)
3 LOAD_CONST 0 (None)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 8 (is)
11 JUMP_IF_FALSE_OR_POP 21
14 LOAD_CONST 0 (None)
17 COMPARE_OP 8 (is)
20 RETURN_VALUE
>> 21 ROT_TWO
22 POP_TOP
23 RETURN_VALUE
Como se indica en los documentos para las comparaciones, esto se debe a que estos operadores se encadenan.
a op b op c
se traducirá a
a op b and b op c
(la nota
b
está duplicada en el código de bytes como se muestra arriba)
is
un operador de comparación,
como se ve en los documentos
:
comparison ::= or_expr ( comp_operator or_expr )* comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!=" | "is" ["not"] | ["not"] "in"
Así que al igual que los otros operadores de comparación, puede ser encadenado arbitrariamente. Asi que
a = b = c = None
a is b is c
es equivalente a
(a is b) and (b is c)