2015-11-26 74 views
4

因此,在python中,可以很容易地檢查真值條件,並且在括號中可以優先考慮真實條件的順序。這很容易理解:Python中的不等式和括號

>>> 3 > 2 
True 
>>> (3 > 2) is True 
True 

但什麼是這些平均,我無法把握的,爲什麼他們返回False /真邏輯:

>>> 3 > 2 is True 
False 
>>> 3 > (2 is True) 
True 
>>> 5 < 3 is False > 2 is True 
False 
>>> 5 < 3 is False is True > 2 is True 
False 
>>> 3 < 5 is True is True > 2 is True 
False 
>>> 3 < 5 is True is True > 2 is True is not False is True 
False 
>>> 3 < 5 is True is (True > 2 is True is not False) is True 
False 
>>> 3 < 5 is True is (True > (2 is True) is not False) is True 
False 
>>> (3 < 5 is True is True) > 2 is (True is not False is True) 
False 

我知道這些都不是Python的條件,但是我應該怎麼理解他們?它是從左到右嗎?

還是is True或/和is False需要主持?

回答

3

您可以使用dis模塊來分析每種情況,以確定發生了什麼。例如:

In [1]: import dis 
In [2]: def test(): 
    ...:  return 3 > 2 is True 
    ...: 
In [3]: dis.dis(test) 
    2   0 LOAD_CONST    1 (3) 
       3 LOAD_CONST    2 (2) 
       6 DUP_TOP    
       7 ROT_THREE   
       8 COMPARE_OP    4 (>) 
      11 JUMP_IF_FALSE_OR_POP 21 
      14 LOAD_GLOBAL    0 (True) 
      17 COMPARE_OP    8 (is) 
      20 RETURN_VALUE   
     >> 21 ROT_TWO    
      22 POP_TOP    
      23 RETURN_VALUE 

這意味着堆棧看起來像這樣每個步驟後:

0: 3 
3: 3 2 
6: 3 2 2 
7: 2 3 2 
8: 2 True 
11: 2 
14: 2 True 
17: False (comparison was: "2 is True") 
20: (False is returned) 

對我來說,它看起來像Python中的錯誤是誠實的。也許有一些很好的解釋,爲什麼會發生這種情況,但我會向上遊彙報。

只是重新改寫了它等價的方式,代碼的作用:

if 3 > 2: 
    if 2 is True: 
     return True 
return False 

編輯:也許這實際上使一些奇怪的那種感覺。考慮如何檢查鏈接的不平等作品:

3 > 2 > 1 == 3 > 2 and 2 > 1 

如果推廣到:

x op1 y op2 z == x op1 y and y op2 z 

可以解釋的結果。

編輯2:這實際上匹配文檔。看一看鏈比較:https://docs.python.org/2/reference/expressions.html#not-in

comparison ::= or_expr (comp_operator or_expr)* 
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!=" 
        | "is" ["not"] | ["not"] "in" 

is被認爲是一樣好比較,因爲>,所以適用於多重比較標準的擴展。

現在應該清楚其他比較。需要的唯一奇怪的新細節是:True == 1False == 0,因此3 > False3 > (2 is True)。大多數其他人可以用擴展來解釋。例如:

5 <  3  is  False  >  2  is True == False 
(5 < 3) and (3 is False) and (False > 2) and (2 is True) == False 
+0

只是想知道,'JUMP_IF_FALSE_OR_POP'操作應該表示什麼? –

+0

字面意思是什麼名稱:)如果堆棧頂部是假的,它會跳轉。如果沒有,它會彈出該值。 – viraptor

+0

對不起,我應該更具體一些:「JUMP」是什麼意思? –

1

首先,你propably需要一點點的小抄知道order of evaluation。大多數這些操作符位於同一個括號內,因此從左到右進行評估。有了這些知識,這些例子可以翻譯它們的「真實」的意思是:

(3 < 5 is True is True) > 2 is (True is not False is True) 

相當於:(其實有沒有__is____not__,因爲這些都是不能超載的關鍵字。這是用於說明目的)

(3.__lt__(5).__is__(True).__is__(True)).__gt__(2).__is__(True.__is__(False).__not__().__is__(True)) 

我可能逃得掉一些細節描述here。好處是你(希望)不會寫出如此複雜的表達式,你需要檢查文檔以瞭解它的功能。

編輯:沒關係,它不會以這種方式與比較工作。比較結果被比較爲「一起成對」,就像viraptor的回答中所描述的一樣。

+1

這實際上是不正確的。看看我的迴應。僅使用比較的表達式會被專門處理。你引用的頁面是「(除了比較,包括測試,它們從左到右全部具有相同的優先級和鏈 - 請參見比較部分和指數,從右到左分組)」。另外「不是」是字節碼中的一個操作符(不管你寫'不是1是2'還是'1不是2')。 – viraptor

+0

我知道這些不準確之處,但我認爲我可以讓他們滑倒插圖。這是文檔中整個部分的一個原因。 – Felk

+1

我的意思是'(3 <5是True)'不等於'3 .__ lt __(5).__是__(True)'。它是'(3 .__ lt __(5))和(5 .__ is __(True))'。 – viraptor

2

Boolean在python中鍵入的類型是int的子類型。所以True實際上是1和False爲0

Python中所有比較運算具有相同的優先級(><>=<===!=is [not][not] in)。

比較可以被任意鏈的,例如,x < y <= z相當於x < y and y <= z,不同之處在於計算y只有一次(但在這兩種情況下Z不是在所有時x < y被發現是假的評價)。

在形式上,如果abc,...,yz是表達式和​​op1op2,...,opN是比較操作符,然後a op1 b op2 c ... y opN z相當於a op1 b and b op2 c and ... y opN z,除了每個表達在評價最多一次。

請參閱Python language reference

+0

但是隻有'1'和'True'之間的值才能檢查出對嗎?所以'真是1'和'1是真'是假的。和「True == 1」和「1 == True」爲真。 – alvas

+0

是的,'True','1'和'1.0'都是不同類型的對象,但具有相同的值。因此,對象身份運算符「是」將總是說它們是不同的。其他比較運算符將始終比較它們的值。 – user2683246