Mengapa “tidak (Benar) dalam [False, True]” mengembalikan False?

483

Jika saya melakukan ini:

>>> False in [False, True]
True

Itu kembali True. Hanya karena Falseada dalam daftar.

Tetapi jika saya lakukan:

>>> not(True) in [False, True]
False

Itu kembali False. Sedangkan not(True)sama dengan False:

>>> not(True)
False

Mengapa?

Texom512
sumber
2
tanda kurung Anda membingungkannot(True) in [False, True]
Grijesh Chauhan

Jawaban:

730

Operator precedence 2.x , 3.x . Diutamakan notlebih rendah dari in. Jadi itu setara dengan:

>>> not ((True) in [False, True])
False

Ini yang Anda inginkan:

>>> (not True) in [False, True]
True

Seperti yang ditunjukkan @Ben: Disarankan untuk tidak pernah menulis not(True), lebih suka not True. Yang pertama membuatnya tampak seperti panggilan fungsi, sementara notadalah operator, bukan fungsi.

Yu Hao
sumber
279
@ Texom512: Saya juga merekomendasikan untuk tidak pernah menulis not(True); lebih suka not True. Yang pertama membuatnya tampak seperti pemanggilan fungsi, dari sanalah kebingungan Anda berasal; jika notfungsi, maka not(True) in ...tidak mungkin not ((True) in ...). Anda harus tahu itu operator (atau Anda berakhir dalam situasi seperti ini), jadi Anda harus menulisnya seperti operator, bukan menyamarkannya sebagai fungsi.
Ben
7
Juga, jika Anda akan menggunakan spasi untuk menunjukkan prioritas untuk kepentingan pembaca, pertama-tama pastikan Anda benar. Mungkin baik untuk menulis a + b*c + d, sangat buruk untuk menulis a+b * c+d. Jadi not(True)buruk dengan ukuran itu juga.
Steve Jessop
32
Sebenarnya, jangan pernah menulis not True. Tulis Falsesaja.
Darkhogg
10
Agaknya dalam kehidupan nyata Anda tidak akan menulis not True, Anda akan menulis sesuatu seperti di not myfunc(x,y,z)mana myfuncbeberapa fungsi yang mengembalikan Trueatau False.
Nate CK
3
@ BenC.R.Leggiero Itulah yang saya lakukan dalam jawaban asli , dan yang lain telah memperbaikinya. Versi saat ini cukup jelas bagi saya, saya pikir itu tidak sulit untuk dipahami tanpa tanda kurung yang berlebihan, karena masalah utama telah ditunjukkan, memahami sisanya adalah keterampilan dasar seorang programmer.
Yu Hao
76

not x in y dievaluasi sebagai x not in y

Anda dapat melihat persis apa yang terjadi dengan membongkar kode. Kasing pertama berfungsi seperti yang Anda harapkan:

>>> x = lambda: False in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (False)
              3 LOAD_GLOBAL              0 (False)
              6 LOAD_GLOBAL              1 (True)
              9 BUILD_LIST               2
             12 COMPARE_OP               6 (in)
             15 RETURN_VALUE

Kasus kedua, dievaluasi menjadi True not in [False, True], yang Falsejelas:

>>> x = lambda: not(True) in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_GLOBAL              1 (False)
              6 LOAD_GLOBAL              0 (True)
              9 BUILD_LIST               2
             12 COMPARE_OP               7 (not in)
             15 RETURN_VALUE        
>>> 

Apa yang ingin Anda ungkapkan adalah (not(True)) in [False, True], yang seperti yang diharapkan True, dan Anda dapat melihat alasannya:

>>> x = lambda: (not(True)) in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (True)
              3 UNARY_NOT           
              4 LOAD_GLOBAL              1 (False)
              7 LOAD_GLOBAL              0 (True)
             10 BUILD_LIST               2
             13 COMPARE_OP               6 (in)
             16 RETURN_VALUE        
Roshan Mathews
sumber
13
Selalu ada seorang pria dengan distetapi ini adalah jawaban yang sangat berharga karena itu menunjukkan bahwa sebenarnya not indigunakan
jamylak
21
Bytecode adalah detail implementasi dari juru bahasa CPython. Ini adalah jawaban CPython untuk pertanyaan Python, bahkan bisa lebih baik dijawab dari referensi bahasa secara langsung.
wim
5
@wim Saya berpendapat bahwa implementasi bytecode tidak sepenting pembongkaran yang sebenarnya. Implementasi lain dijamin untuk menghasilkan sesuatu yang identik secara fungsional, sehingga pemahaman satu pembongkaran menawarkan wawasan yang cukup untuk memahami "mengapa" dan bukan tingkat rendah "bagaimana".
Alex Pana
36

Diutamakan operator. inmengikat lebih erat daripada not, jadi ekspresi Anda setara dengan not((True) in [False, True]).

mooiamaduck
sumber
33

Ini semua tentang prioritas operator ( inlebih kuat dari not). Tapi itu dapat dengan mudah diperbaiki dengan menambahkan tanda kurung di tempat yang tepat:

(not(True)) in [False, True]  # prints true

penulisan:

not(True) in [False, True]

sama seperti:

not((True) in [False, True])

yang terlihat jika Trueada dalam daftar dan mengembalikan "tidak" dari hasilnya.

Alfasin
sumber
14

Ini mengevaluasi sebagai not True in [False, True], yang mengembalikan Falsekarena Trueada di[False, True]

Jika kamu mencoba

>>>(not(True)) in [False, True]
True

Anda mendapatkan hasil yang diharapkan.

pengguna3636636
sumber
13

Di samping jawaban lain yang menyebutkan prioritas notlebih rendah daripada in, sebenarnya pernyataan Anda setara dengan:

not (True in [False, True])

Tetapi perhatikan bahwa jika Anda tidak memisahkan kondisi Anda dari yang lain, python akan menggunakan 2 peran ( precedenceatau chaining) untuk memisahkannya, dan dalam hal ini python menggunakan prioritas. Juga, perhatikan bahwa jika Anda ingin memisahkan suatu kondisi Anda harus meletakkan semua kondisi dalam tanda kurung bukan hanya objek atau nilai:

(not True) in [False, True]

Tapi seperti yang disebutkan, ada modifikasi lain oleh python pada operator yang chaining :

Berdasarkan dokumentasi python :

Perhatikan bahwa perbandingan, tes keanggotaan, dan tes identitas, semua memiliki hak yang sama dan memiliki kiri ke kanan chaining fitur seperti yang dijelaskan di bagian Perbandingan.

Misalnya hasil dari pernyataan berikut adalah False:

>>> True == False in [False, True]
False

Karena python akan mem-chain pernyataan seperti berikut:

(True == False) and (False in [False, True])

Yang tepatnya False and Trueitu False.

Anda dapat mengasumsikan bahwa objek pusat akan dibagi antara 2 operasi dan objek lainnya (Salah dalam kasus ini).

Dan perhatikan bahwa ini juga berlaku untuk semua Perbandingan, termasuk tes keanggotaan dan operasi tes identitas yang mengikuti operan:

in, not in, is, is not, <, <=, >, >=, !=, ==

Contoh:

>>> 1 in [1,2] == True
False

Contoh terkenal lainnya adalah rentang angka:

7<x<20

yang sama dengan:

7<x and x<20   
Kasramvd
sumber
6

Mari kita melihatnya sebagai operasi pengecekan penahanan koleksi: [False, True]adalah daftar yang berisi beberapa elemen.

Ekspresi True in [False, True]kembali True, seperti Trueelemen yang terkandung dalam daftar.

Oleh karena itu, not True in [False, True]berikan "boolean berlawanan", nothasil dari ekspresi di atas (tanpa tanda kurung untuk mempertahankan prioritas, karena inmemiliki prioritas lebih besar daripada notoperator). Karena itu, not Trueakan dihasilkan False.

Di sisi lain,, (not True) in [False, True]sama dengan False in [False, True], yaitu True( Falsetercantum dalam daftar).

Nick Louloudakis
sumber
6

Untuk mengklarifikasi beberapa jawaban lain, menambahkan tanda kurung setelah operator unary tidak mengubah prioritasnya. not(True)tidak membuat notikatan lebih erat ke True. Itu hanya sekumpulan tanda kurung yang berlebihan True. Sama seperti (True) in [True, False]. Tanda kurung tidak melakukan apa pun. Jika Anda ingin pengikatan lebih kencang, Anda harus meletakkan tanda kurung di seluruh ekspresi, yang berarti operator dan operan, yaitu (not True) in [True, False],.

Untuk melihat ini dengan cara lain, pertimbangkan

>>> -2**2
-4

**mengikat lebih erat daripada -, itulah sebabnya Anda mendapatkan negatif dua kuadrat, bukan kuadrat dua negatif (yang akan positif empat).

Bagaimana jika Anda ingin kuadrat dari dua negatif? Jelas, Anda akan menambahkan tanda kurung:

>>> (-2)**2
4

Namun, tidak masuk akal untuk mengharapkan yang berikut diberikan 4

>>> -(2)**2
-4

karena -(2)sama dengan -2. Tanda kurung sama sekali tidak melakukan apa pun. not(True)persis sama.

penilai
sumber