“[Yanlış, Doğru]” daki (Doğru) neden Yanlış döndürmüyor?


483

Bunu yaparsam:

>>> False in [False, True]
True

Geri dönüyor True. Sadece Falselistede olduğu için.

Ama eğer yaparsam:

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

Geri dönüyor False. Halbuki not(True)eşittir False:

>>> not(True)
False

Neden?



2
parantezleriniz kafa karıştırıyornot(True) in [False, True]
Grijesh Chauhan

Yanıtlar:


730

Operatör önceliği 2.x , 3.x . Önceliği, notöncekinden daha düşüktür in. Yani şuna eşittir:

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

Senin istediğin bu:

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

@Ben işaret ettiği gibi: O yazma asla önerilir not(True), tercih not True. Birincisi bir işlev çağrısı gibi görünmesini sağlarken not, bir işlev değil, bir işleçtir.


279
@ Texom512: Ayrıca asla yazmamayı öneririm not(True); tercih edin not True. Birincisi, karışıklığınızın geldiği bir işlev çağrısı gibi görünmesini sağlar; eğer notbir işlev olsaydı , o zaman not(True) in ...olamazdı not ((True) in ...). Bunun bir operatör olduğunu bilmelisiniz (ya da bunun gibi durumlarda ortaya çıkıyorsunuz), bu yüzden onu bir işlev olarak gizlememeli, bir operatör gibi yazmalısınız.
Ben

7
Ayrıca, okuyucunun yararına olan önceliği belirtmek için boşluk kullanacaksanız, önce doğru olduğunuzdan emin olun. Yazmak muhtemelen sorun değil, yazmak a + b*c + dçok kötü a+b * c+d. Bu not(True)önlem için de kötü.
Steve Jessop

32
Aslında, asla yazma not True. FalseBunun yerine yazın .
Darkhogg

10
Tahminen gerçek hayatta yazmakta olmaz not True, gibi bir şey yazmaya olurdum not myfunc(x,y,z)nerede myfuncbazı fonksiyon olduğunu getirileridir Trueveya False.
Nate CK

3
@ BenC.R. Laggiero Orijinal cevapta yaptığım şey bu ve diğerleri bunu düzeltti. Mevcut sürüm benim için yeterince açık, gereksiz parantezler olmadan anlamanın zor olduğunu düşünmüyorum, çünkü kilit problem işaret edildi, gerisini anlamak bir programcının temel becerisidir.
Yu Hao

76

not x in y olarak değerlendirilir x not in y

Kodu sökerek neler olduğunu tam olarak görebilirsiniz. İlk vaka beklediğiniz gibi çalışır:

>>> 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

İkinci durumda, değerlendirir True not in [False, True]hangi, Falseaçık bir şekilde:

>>> 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        
>>> 

Bunun yerine ifade etmek istediğiniz şey (not(True)) in [False, True], beklendiği gibi Trueve nedenini görebilirsiniz:

>>> 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        

13
Her zaman bir adam var disama bu çok değerli bir cevap çünkü aslında not inkullanıldığını gösteriyor
jamylak

21
Bayt kodu, CPython yorumlayıcısının uygulama detayıdır. Bu bir Python sorusuna bir CPython cevabıdır, aslında doğrudan dil referansından daha iyi cevaplanabilir.
wim

5
@wim Bayt kodu uygulamasının gerçek demontaj kadar önemli olmadığını savunuyorum. Diğer uygulamaların işlevsel olarak özdeş bir şey üretmesi garanti edilir, bu nedenle bir sökme işleminin anlaşılması, düşük seviyeli "nasıl" değil, "neden" i anlamak için yeterli bilgi sağlar.
Alex Pana

36

Operatör Önceliği. indaha sıkı bağlanır not, böylece ifadeniz eşdeğerdir not((True) in [False, True]).


33

Her şey operatör önceliği ile ilgilidir ( indaha güçlüdür not). Ancak doğru yere parantez ekleyerek kolayca düzeltilebilir:

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

yazı:

not(True) in [False, True]

aynı:

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

Truelistede olup olmadığına bakar ve sonucun "değil" değerini döndürür.


14

Sanki değerlendirmekte olan not True in [False, True]hangi döner, Falseçünkü Trueiçindedir[False, True]

Eğer denersen

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

Beklenen sonucu alırsınız.


13

Önceliğinden bahseten diğer cevapların yanı sıra, ifadeniz aslında notdaha düşüktür in:

not (True in [False, True])

Ancak, durumunuzu diğerlerinden ayırmazsanız, python'un bunu ayırmak için 2 rol ( precedenceveya chaining) kullanacağını ve bu durumda python'un önceliği kullandığını unutmayın. Ayrıca, bir koşulu ayırmak istiyorsanız, tüm koşulu yalnızca nesne veya değeri değil parantez içine almanız gerektiğini unutmayın:

(not True) in [False, True]

Ancak belirtildiği gibi, python tarafından zincirleme yapan operatörler üzerinde başka bir değişiklik var :

Python belgelerine dayanarak :

Karşılaştırmaların, üyelik testlerinin ve kimlik testlerinin hepsinin önceliği aynıdır ve Karşılaştırmalar bölümünde açıklandığı gibi soldan sağa zincirleme özelliğine sahiptir.

Örneğin, aşağıdaki ifadenin sonucu False:

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

Çünkü python aşağıdaki gibi ifadeleri zincirleyecektir:

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

Hangisi tam olarak False and TruebuFalse .

Merkezi nesnenin 2 işlem ve diğer nesneler arasında paylaşılacağını varsayabilirsiniz (bu durumda False).

Ayrıca, işlenenleri takip eden üyelik testleri ve kimlik testleri işlemleri de dahil olmak üzere tüm Karşılaştırmalar için de geçerli olduğunu unutmayın:

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

Misal :

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

Bir başka ünlü örnek sayı aralığıdır:

7<x<20

ki şuna eşittir:

7<x and x<20   

6

Bunu bir toplama sınırlama denetimi işlemi olarak görelim: [False, True]bazı öğeleri içeren bir listedir.

İfade , listede bulunan bir öğe gibi True in [False, True]döner .TrueTrue

Bu nedenle, yukarıdaki ifadenin not True in [False, True]"boole tersi" notsonucunu verir ( operatöre ingöre daha yüksek önceliğe sahip olduğu gibi , önceliği korumak için herhangi bir parantez olmadan not). Bu nedenle, not Truesonuçlanır False.

Öte yandan, (not True) in [False, True]eşittir False in [False, True], True( Falselistede yer alır).


6

Diğer cevaplardan bazılarını açıklığa kavuşturmak için, tekli bir operatörden sonra parantez eklemek önceliğini değiştirmez. bağlamayı daha sıkı not(True)yapmaz . Bu sadece bir parantez seti . Oldukça aynı . Parantezler hiçbir şey yapmaz. Bağlamanın daha sıkı olmasını istiyorsanız, parantezleri tüm ifadenin etrafına koymanız gerekir, yani hem işleç hem de işlenen, yani .notTrueTrue(True) in [True, False](not True) in [True, False]

Bunu başka bir şekilde görmek için,

>>> -2**2
-4

**daha sıkı bağlanır -, bu yüzden negatif iki kareyi değil, iki karenin negatifini alırsınız (ki bu pozitif dört olacaktır).

Negatif iki kareyi isteseydiniz ne olurdu? Açıkçası, parantez eklersiniz:

>>> (-2)**2
4

Ancak, aşağıdakilerin verilmesi beklenemez 4

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

çünkü -(2)ile aynıdır -2. Parantezler kesinlikle hiçbir şey yapmıyor. not(True)tamamen aynı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.