Mengapa (1 dalam [1,0] == Benar) dievaluasi menjadi Salah?

153

Ketika saya melihat jawaban untuk pertanyaan ini , saya menemukan saya tidak mengerti jawaban saya sendiri.

Saya tidak begitu mengerti bagaimana ini diurai. Mengapa contoh kedua mengembalikan 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

Terima kasih atas bantuannya. Saya pikir saya harus kehilangan sesuatu yang sangat jelas.


Saya pikir ini agak berbeda dengan duplikat yang ditautkan:

Mengapa ekspresi 0 <0 == 0 mengembalikan False in Python? .

Kedua pertanyaan tersebut berkaitan dengan pemahaman manusia tentang ekspresi. Tampaknya ada dua cara (dalam pikiranku) untuk mengevaluasi ekspresi. Tentu saja tidak ada yang benar, tetapi dalam contoh saya, interpretasi terakhir tidak mungkin.

Melihat 0 < 0 == 0Anda dapat membayangkan setiap bagian dievaluasi dan masuk akal sebagai ungkapan:

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

Jadi tautan menjawab mengapa ini mengevaluasi False:

>>> 0 < 0 == 0
False

Tetapi dengan contoh saya 1 in ([1,0] == True)tidak masuk akal sebagai ungkapan, jadi alih-alih ada dua kemungkinan penafsiran, hanya satu yang tampaknya mungkin:

>>> (1 in [1,0]) == True
Peter Wood
sumber
1
Diutamakan operator ... ==ikatan lebih ketat daripada in, jadi [1,0] == Truedievaluasi dulu, lalu hasilnya diumpankan ke 1 in other_result.
Marc B
Saya telah menghapus tag Python-2.7, karena Python 3.2 berperilaku dengan cara yang sama.
lvc
1
@ Mark B: Tidak menjelaskan ungkapan kedua
Scott Hunter
32
@ MarcB, pertanyaannya termasuk tes menggunakan tanda kurung untuk menyangkal interpretasi itu.
Mark Ransom

Jawaban:

194

Python sebenarnya menerapkan chaining operator perbandingan di sini. Ekspresi diterjemahkan ke

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

yang jelas False.

Ini juga terjadi untuk ekspresi seperti

a < b < c

yang diterjemahkan menjadi

(a < b) and (b < c)

(tanpa mengevaluasi bdua kali).

Lihat dokumentasi bahasa Python untuk perincian lebih lanjut.

Sven Marnach
sumber
40
Bukti tambahan untuk ini, 1 in [1, 0] == [1, 0]dievaluasi menjadi True.
Andrew Clark
9
Saya sudah lama menganggap ini sebagai kutil bahasa. Saya lebih suka bahwa inoperator memiliki prioritas lebih tinggi daripada operator perbandingan lainnya dan tidak berantai. Tapi mungkin saya melewatkan use case.
Steven Rumbalski
3
tangkapan yang bagus, aku bahkan tidak memikirkan itu. Tidak masuk akal untuk membiarkan rantai in- setelah semua x < y < zmasuk akal, tetapi tidak begitu banyak denganx in y in z
BlueRaja - Danny Pflughoeft
7
@ Bahkan Berguna: mungkin. Dapat dibaca: jelas tidak. Python bermaksud untuk meniru tipografi matematika umum dengan konvensi ini, tetapi ketika digunakan dengan inini tidak lagi terjadi dan membuatnya cukup kontra-intuitif.
Konrad Rudolph
6
@KonradRudolph: Saya pernah melihat berpikir seperti "1 ≤ x ∈ ℝ" dalam teks matematika lebih dari sekali, tetapi pada dasarnya saya setuju dengan Anda.
Sven Marnach