Qual é o significado de "(1,) == 1" no Python?

119

Estou testando a estrutura da tupla e achei estranho quando uso o ==operador como:

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

Quando atribuo essas duas expressões a uma variável, o resultado é verdadeiro:

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

Esta pergunta é diferente da regra de sintaxe de vírgula à direita da tupla do Python, na minha opinião. Eu pergunto ao grupo de expressões entre ==operador.

Pythoner
fonte
16
Olhando para uma pergunta anterior do OP, há apenas duas horas, parece maravilhoso (ou estranho) que o modo como a elaboração de uma pergunta de maneira diferente possa levar a resultados diferentes (e aceitação entre a comunidade).
AKS
24
@AKS Estes são diferentes qestions
kmaork
7
@AKS Embora as perguntas sejam ligeiramente diferentes aqui, concordo totalmente com o seu ponto. Efeito de rebanho, também conhecido como HNQ.
Insano
5
@PythonNewHand De fato, é completamente aceitável. Foi por isso que adicionei esse enquadramento de uma pergunta de maneira diferente .
AKS
3
@CiroSantilli 法轮功 文件 六四 事件 法轮功 como você figura? Eu olhei essas respostas e não vi nada que parecesse cobrir essa situação específica.
Dan Getz

Respostas:

88

Outras respostas já mostraram que o comportamento é devido à precedência do operador, conforme documentado aqui .

Vou mostrar a você como encontrar a resposta da próxima vez que tiver uma pergunta semelhante a essa. Você pode desconstruir como a expressão analisa usando o 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 disso, podemos ver que o código é analisado como Tim Peters explicou :

Module([Expr(
    Tuple([
        Compare(
            Tuple([Num(1)], Load()), 
            [Eq()], 
            [Num(1)]
        )
    ], Load())
)])
wim
fonte
1
Outra ferramenta útil é dis: nesse caso, você verá dois LOAD_CONSTcom valores diferentes ( (1,)e 1) e um BUILD_TUPLEcódigo opp.
mgilson
153

Esta é apenas a precedência do operador. Você primeiro

(1,) == 1,

grupos assim:

((1,) == 1),

então cria uma tupla com um único elemento a partir do resultado da comparação da tupla de um elemento 1,com o número inteiro 1para igualdade. Eles não são iguais, então você obtém a tupla de 1 False,para um resultado.

Tim Peters
fonte
61
Na verdade não, mas as tuplas 1 têm sintaxe ímpar. Em geral, você estaria muito mais surpreso se, por exemplo, 1+2, 2==3, 4*7fez não grupo como (1+2), (2==3), (4*7). Na prática, as tuplas 1 quase nunca são usadas (bem, fora das perguntas do StackOverflow ;-)).
Tim Peters
6
Talvez "inesperado" fosse uma palavra melhor para usar do que "estranho". Sinto um pouco como se estivesse olhando para um desses desenhos que podem ser duas coisas, dependendo da sua perspectiva e foco . O operador de igualdade é tão grande em comparação com as vírgulas, é fácil focar nele e assumir que o resultado será True/ False. Agora que eu entendo o que está acontecendo, é perfeitamente óbvio e razoável.
Skrrgwasme 19/05
31
E agora você sabe o que o "Zen do Python" significa dizendo que a única maneira óbvia de fazê-lo "pode ​​não ser óbvia a princípio, a menos que você seja holandês" ;-) #
Tim Tim Peters
7
É um pouco confuso quando você lê o documento e vê que o que faz uma tupla é a vírgula, não os parênteses! Portanto, nesta declaração, a vírgula na mão direita não é considerada como parte do teste, mas como um separador! Comportamento inesperado!
Ikra_5
3
O conselho comum sobre expressões é "em caso de dúvida, use parênteses". Depois disso, é bom colocar parênteses em torno de todas as tuplas, mesmo que elas não façam parte da sintaxe da tupla.
Nigel222
12

Quando você faz

>>> (1,) == 1,

ele cria uma tupla com o resultado da comparação da tupla (1,) com um número inteiro e, assim, retornando False.

Em vez disso, quando você atribui a variáveis, as duas tuplas iguais são comparadas entre si.

Podes tentar:

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