Dlaczego (1 w [1,0] == Prawda) daje wynik Fałsz?

153

Kiedy szukałem odpowiedzi na to pytanie , stwierdziłem, że nie rozumiem własnej odpowiedzi.

Naprawdę nie rozumiem, jak to jest analizowane. Dlaczego drugi przykład zwraca 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

Dzięki za wszelką pomoc. Myślę, że brakuje mi czegoś naprawdę oczywistego.


Myślę, że różni się to nieco od połączonego duplikatu:

Dlaczego wyrażenie 0 <0 == 0 zwraca False w Pythonie? .

Obydwa pytania dotyczą ludzkiego zrozumienia wyrażenia. Wydawało się, że istnieją dwa sposoby (moim zdaniem) oceny wyrażenia. Oczywiście żadne z nich nie było poprawne, ale w moim przykładzie ostatnia interpretacja jest niemożliwa.

Patrząc na 0 < 0 == 0ciebie, możesz sobie wyobrazić, że każda połowa jest oceniana i ma sens jako wyrażenie:

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

Tak więc link odpowiada, dlaczego to ocenia False:

>>> 0 < 0 == 0
False

Ale z moim przykładem 1 in ([1,0] == True)nie ma sensu jako wyrażenie, więc zamiast dwóch (co prawda błędnych) możliwych interpretacji, tylko jedna wydaje się możliwa:

>>> (1 in [1,0]) == True
Peter Wood
źródło
1
Priorytet operatorów ... ==powiązania są mocniejsze niż in, więc [1,0] == Truejest oceniane jako pierwsze, a następnie wynik tego jest podawany 1 in other_result.
Marc B
Usunąłem tag Python-2.7, ponieważ Python 3.2 zachowuje się w ten sam sposób.
lvc
1
@Marc B: Nie wyjaśnia drugiego wyrażenia
Scott Hunter,
32
@MarcB, pytanie obejmowało test z użyciem nawiasów, aby obalić tę interpretację.
Mark Ransom,

Odpowiedzi:

194

W rzeczywistości Python stosuje tutaj łańcuchowanie operatorów porównania. Wyrażenie jest tłumaczone na

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

co oczywiście jest False .

Dzieje się tak również w przypadku wyrażeń takich jak

a < b < c

co przekłada się na

(a < b) and (b < c)

(bez oceniania b podwójnej ).

Więcej informacji można znaleźć w dokumentacji języka Python .

Sven Marnach
źródło
40
Dodatkowy dowód na to, 1 in [1, 0] == [1, 0]ocenia do True.
Andrew Clark,
9
Od dawna myślałem o tym jako o brodawce językowej. Wolałbym, aby inoperator miał wyższy priorytet niż inne operatory porównania, a nie łańcuch. Ale być może brakuje mi przypadku użycia.
Steven Rumbalski
3
niezły chwyt, nawet o tym nie pomyślałem. Nie ma sensu pozwalać na łączenie in- w końcu x < y < zma to sens, ale nie tak bardzo zx in y in z
BlueRaja - Danny Pflughoeft
7
@Sven Useful: może. Czytelne: zdecydowanie nie. Python rzekomo emuluje typową typografię matematyczną z tą konwencją, ale gdy jest używany z tą konwencją, po inprostu nie ma już miejsca i sprawia, że ​​jest to dość sprzeczne z intuicją.
Konrad Rudolph,
6
@KonradRudolph: Widziałem myśli typu "1 ≤ x ∈ ℝ" w tekstach matematycznych więcej niż raz, ale zasadniczo się z tobą zgadzam.
Sven Marnach