Perché (1 in [1,0] == Vero) viene valutato come Falso?


153

Quando stavo guardando le risposte a questa domanda , ho scoperto di non aver capito la mia risposta.

Non capisco davvero come questo venga analizzato. Perché il secondo esempio restituisce False?

>>> 1 in [1,0]             # This is expected
True
>>> 1 in [1,0] == True     # This is strange
False
>>> (1 in [1,0]) == True   # This is what I wanted it to be
True
>>> 1 in ([1,0] == True)   # But it's not just a precedence issue!
                           # It did not raise an exception on the second example.

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    1 in ([1,0] == True)
TypeError: argument of type 'bool' is not iterable

Grazie per qualsiasi aiuto. Penso che mi debba mancare qualcosa di veramente ovvio.


Penso che questo sia leggermente diverso dal duplicato collegato:

Perché l'espressione 0 <0 == 0 restituisce False in Python? .

Entrambe le domande hanno a che fare con la comprensione umana dell'espressione. Sembrava che ci fossero due modi (secondo me) di valutare l'espressione. Naturalmente nessuno dei due era corretto, ma nel mio esempio l'ultima interpretazione è impossibile.

Guardandoti 0 < 0 == 0puoi immaginare che ogni metà venga valutata e abbia senso come espressione:

>>> (0 < 0) == 0
True
>>> 0 < (0 == 0)
True

Quindi il link risponde al motivo per cui questo valuta False:

>>> 0 < 0 == 0
False

Ma con il mio esempio 1 in ([1,0] == True)non ha senso come espressione, quindi invece di avere due possibili interpretazioni (certamente errate), solo una sembra possibile:

>>> (1 in [1,0]) == True

1
Precedenza dell'operatore ... il ==legame è più stretto di in, quindi [1,0] == Trueviene valutato prima, quindi il risultato viene alimentato 1 in other_result.
Marc B,

Ho rimosso il tag Python-2.7, poiché Python 3.2 si comporta allo stesso modo.
PVC

1
@Marc B: non spiega la seconda espressione
Scott Hunter,

32
@MarcB, la domanda includeva un test che utilizzava le parentesi per confutare quell'interpretazione.
Mark Ransom,

Risposte:


194

Python applica effettivamente l'operatore di confronto concatenato qui. L'espressione è tradotta in

(1 in [1, 0]) and ([1, 0] == True)

che è ovviamente False.

Questo succede anche per espressioni come

a < b < c

che traducono in

(a < b) and (b < c)

(senza valutare bdue volte).

Consulta la documentazione del linguaggio Python per ulteriori dettagli.


40
Ulteriori prove per questo, 1 in [1, 0] == [1, 0]valuta True.
Andrew Clark,

9
Ci ho pensato a lungo come una verruca linguistica. Avrei preferito che l' inoperatore avesse una precedenza maggiore rispetto ad altri operatori di confronto e che non si incatenasse. Ma forse mi manca un caso d'uso.
Steven Rumbalski,

3
bella cattura, non ci avevo nemmeno pensato. Non ha molto senso permettere il concatenamento in- dopo tutto x < y < zha senso, ma non tanto conx in y in z
BlueRaja - Danny Pflughoeft

7
@Sven Utile: forse. Leggibile: sicuramente no. Python pretende di emulare la tipografia matematica comune con questa convenzione, ma se usato con inquesto semplicemente non è più il caso e lo rende abbastanza contro-intuitivo.
Konrad Rudolph,

6
@KonradRudolph: ho visto pensare "1 ≤ x ∈ ℝ" nei testi matematici più di una volta, ma sono sostanzialmente d'accordo con te.
Sven Marnach,
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.