¿Cuál es el significado de "(1,) == 1," en Python?

119

Estoy probando la estructura de la tupla y me parece extraño cuando uso el ==operador como:

>>>  (1,) == 1,
Out: (False,)

Cuando asigno estas dos expresiones a una variable, el resultado es verdadero:

>>> a = (1,)
>>> b = 1,
>>> a==b
Out: True

Esta pregunta es diferente de la regla de sintaxis de coma final de tuplas de Python en mi opinión. Le pregunto al grupo de expresiones entre ==operador.

Pythoner
fuente
16
Mirando una pregunta anterior del OP hace solo 2 horas, parece maravilloso (o extraño) cómo el simple hecho de enmarcar una pregunta de manera diferente puede conducir a resultados diferentes (y aceptación entre la comunidad).
AKS
24
@AKS Estas son preguntas diferentes
kmaork
7
@AKS Si bien las preguntas son ligeramente diferentes aquí, estoy completamente de acuerdo con su punto. Efecto manada también conocido como HNQ.
Insane
5
@PythonNewHand De hecho, es completamente aceptable. Es por eso que agregué que enmarcando una pregunta de manera diferente .
AKS
3
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 ¿cómo te imaginas? Hojeé esas respuestas y no vi nada que pareciera cubrir esta situación en particular.
Dan Getz

Respuestas:

88

Otras respuestas ya le han mostrado que el comportamiento se debe a la precedencia del operador, como se documenta aquí .

Le mostraré cómo encontrar la respuesta usted mismo la próxima vez que tenga una pregunta similar a esta. Puede deconstruir cómo se analiza la expresión utilizando el astmódulo:

>>> import ast
>>> source_code = '(1,) == 1,'
>>> print(ast.dump(ast.parse(source_code), annotate_fields=False))
Module([Expr(Tuple([Compare(Tuple([Num(1)], Load()), [Eq()], [Num(1)])], Load()))])

A partir de esto, podemos ver que el código se analiza como explicó Tim Peters :

Module([Expr(
    Tuple([
        Compare(
            Tuple([Num(1)], Load()), 
            [Eq()], 
            [Num(1)]
        )
    ], Load())
)])
wim
fuente
1
Otra herramienta útil es dis: en este caso, verá dos LOAD_CONSTcon valores diferentes ( (1,)y 1) y un BUILD_TUPLEcódigo opp.
mgilson
153

Esto es solo la precedencia del operador. Tu primero

(1,) == 1,

grupos así:

((1,) == 1),

por lo que construye una tupla con un solo elemento a partir del resultado de comparar la tupla de un elemento 1,con el número entero 1para determinar la igualdad. No son iguales, por lo que obtiene la tupla 1 False,como resultado.

Tim Peters
fuente
61
En realidad no, pero las tuplas 1 tienen una sintaxis extraña. En general, se sorprendería mucho más si, por ejemplo, 1+2, 2==3, 4*7no se agrupara como (1+2), (2==3), (4*7). En la práctica, las tuplas 1 casi nunca se usan (bueno, fuera de las preguntas de StackOverflow ;-)).
Tim Peters
6
Quizás "inesperado" hubiera sido una mejor palabra que "extraño". Me siento un poco como si estuviera mirando uno de esos dibujos que pueden ser dos cosas, dependiendo de tu perspectiva y enfoque . El operador de igualdad es tan grande en comparación con las comas, es fácil enfocarse en él y asumir que el resultado será True/ False. Ahora que entiendo lo que está pasando, es perfectamente obvio y razonable.
skrrgwasme
31
Y ahora sabes lo que significa el "Zen de Python" al decir que la única forma obvia de hacerlo "puede no ser obvia al principio a menos que seas holandés" ;-)
Tim Peters
7
Es un poco confuso cuando lees el documento y ves que lo que hace una tupla es la coma, ¡no el paréntesis! Entonces, en esta declaración, la coma en la mano derecha no se considera como parte de la prueba, ¡pero se considera como un separador! Comportamiento inesperado!
Ikra_5
3
El consejo común sobre las expresiones es "en caso de duda, utilice paréntesis". Después de eso, es bueno poner paréntesis alrededor de todas las tuplas, aunque no formen parte de la sintaxis de la tupla.
nigel222
12

Cuando tu lo hagas

>>> (1,) == 1,

construye una tupla con el resultado de comparar la tupla (1,) con un entero y, por lo tanto, regresa False.

En cambio, cuando asigna a variables, los dos tuplas iguales se comparan entre sí.

Puedes probar:

>>> x = 1,
>>> x
(1,)
mng
fuente