Qual è il significato di "(1,) == 1," in Python?


119

Sto testando la struttura della tupla e ho scoperto che è strano quando utilizzo l' ==operatore come:

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

Quando assegno queste due espressioni a una variabile, il risultato è vero:

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

Questa domanda è diversa dalla regola di sintassi della virgola finale della tupla di Python a mio avviso. Chiedo al gruppo di espressioni tra ==operatore.


16
Guardando una domanda precedente dell'OP appena 2 ore fa, sembra meraviglioso (o strano) come il semplice inquadrare una domanda in modo diverso possa portare a risultati diversi (e accettazione da parte della comunità).
AKS

24
@AKS Queste sono domande diverse
kmaork

7
@AKS Anche se qui le domande sono leggermente diverse, sono completamente d'accordo con il tuo punto. Effetto mandria aka HNQ.
Insane

5
@ PythonNewHand In effetti, è completamente accettabile. Ecco perché l'ho aggiunto inquadrando una domanda in modo diverso .
AKS

3
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 come fai a capire? Ho passato in rassegna quelle risposte e non ho visto nulla che sembrasse coprire questa particolare situazione.
Dan Getz

Risposte:


88

Altre risposte ti hanno già mostrato che il comportamento è dovuto alla precedenza degli operatori, come documentato qui .

Ti mostrerò come trovare la risposta da solo la prossima volta che hai una domanda simile a questa. Puoi decostruire il modo in cui l'espressione analizza usando il astmodulo:

>>> 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()))])

Da questo possiamo vedere che il codice viene analizzato come spiegato da Tim Peters :

Module([Expr(
    Tuple([
        Compare(
            Tuple([Num(1)], Load()), 
            [Eq()], 
            [Num(1)]
        )
    ], Load())
)])

1
Un altro strumento utile è dis: in questo caso, ne vedresti due LOAD_CONSTcon valori diversi ( (1,)e 1) e un BUILD_TUPLEcodice opp.
mgilson

153

Questa è solo la precedenza degli operatori. Prima tu

(1,) == 1,

gruppi in questo modo:

((1,) == 1),

quindi costruisce una tupla con un singolo elemento dal risultato del confronto tra la tupla 1,di un elemento e il numero intero 1per l'uguaglianza. Non sono uguali, quindi ottieni la tupla 1 False,come risultato.


61
Non proprio, ma le tuple 1 hanno una sintassi strana. In generale, devi essere molto più sorpreso se, ad esempio, 1+2, 2==3, 4*7ha fatto non gruppo (1+2), (2==3), (4*7). In pratica, le tuple da 1 non vengono quasi mai utilizzate (beh, al di fuori delle domande StackOverflow ;-)).
Tim Peters

6
Forse "inaspettato" sarebbe stata una parola migliore da usare di "strano". Mi sento un po 'come se stessi guardando uno di quei disegni che possono essere due cose, a seconda della tua prospettiva e del tuo focus . L'operatore di uguaglianza è così grande rispetto alle virgole, è facile concentrarsi su di esso e assumere che il risultato sarà True/ False. Ora che ho capito cosa sta succedendo, è perfettamente ovvio e ragionevole.
skrrgwasme

31
E ora sai cosa significa "Zen of Python" dicendo che l'unico modo ovvio per farlo "potrebbe non essere ovvio all'inizio a meno che tu non sia olandese" ;-)
Tim Peters

7
È un po 'confuso quando leggi il documento e vedi che ciò che fa una tupla è la virgola, non le parentesi! Quindi in questa affermazione la virgola nella mano destra non è considerata come una parte del test ma è considerata come un separatore! Comportamento inaspettato!
Ikra_5

3
Un consiglio comune sulle espressioni è "in caso di dubbio, usa le parentesi". Successivamente, è bene mettere le parentesi attorno a tutte le tuple, anche se non fanno parte della sintassi della tupla.
nigel222

12

Quando lo fai

>>> (1,) == 1,

costruisce una tupla con il risultato del confronto della tupla (1,) con un intero e quindi restituisce False.

Invece, quando si assegnano a variabili, le due tuple uguali vengono confrontate tra loro.

Puoi provare:

>>> x = 1,
>>> x
(1,)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.