2017-01-05 26 views
3

我剛剛在我的代碼中遇到了一個奇怪的錯誤,這是因爲我在條件中使用了逗號而不是and關鍵字。請參閱下面的代碼爲淡化例如:這個條件如何處理?

def foo(): 
    s = set([1, 2, 3]) 
    a = 4 
    b = 5 
    if (a, b in s):  # Should have been: if (a and b in s): 
     print "Foo" 

foo() # prints "Foo" 

爲什麼條件評估爲True?即使aNone,也會打印「Foo」。

+2

我想你已經創建了一個元組。它由'a'和'b in s'的結果組成,並且您正在測試元組的真實性。 –

回答

7

表達式(a, b in s)是一個有效的Python元組。無論其內容如何,​​只要它至少有一個元素,它就會評估爲真。 (這個有兩個)。

+0

謝謝你的解釋 - 當我剛剛評估過'(a,b in s)'並且返回了一個元組時,我應該發佈了這個。後見之明!一旦10分鐘計時器用完,我會接受這個答案。 – Joseph

3

這是因爲(a, b in s)評估爲長度爲2的元組(4, False),並且在python中,如果元組長度不爲零,則認爲它是True

2

的原因的代碼打印「富」無論和閹b的值是在s是行:

(a, b in s)

實際上是一個元組。 if語句檢查元組是否存在,並且它確實會打印Foo。 當

s=set([1,2,3]) 
a=None 
b=5 

檢查的條件是

if(None, False): 

因爲

(None, False) #is a non empty tuple. 
+0

(寫成「tuple」,而不是「tupule」) – jsbueno

+0

@jsbueno謝謝 –

0

正如其他人所說,表達a, b in s創建一個元組這始終是真實的,非空的元組是truthy,即它在布爾上下文中計算爲True。請注意,逗號會創建元組,而不是括號,儘管在某些上下文中需要使用括號以避免歧義,例如,當將元組文字作爲單個函數參數傳遞時。

順便說一句,Python中的if語句的條件表達式不需要使用括號。他們不會傷害,但通常的風格習慣是將它們省略爲不必要的混亂。

注意if a and b in s:測試,如果雙方ab是集s的元素。要執行測試,您應該使用set.issuperset方法:

if s.issuperset((a, b)): 

請注意,我們這裏需要額外的括號,因爲我們傳遞的元組a, b作爲一個參數。

該聲明也可以使用的.issuperset操作形式寫出:

if s >= set((a, b)): 

但使用這種形式,當兩個操作數必須是集(或frozensets),而完整的方法將接受任何可迭代的其他 arg。

但回到你的代碼...表達

a and b in s 

相當於

a and (b in s) 

如果a是假肥胖型(即,False,0或空集)的表達式求aand表達的第二部分被忽略。否則(當a是真值ish時)and表達式的第二部分被評估並且成爲結果。

換句話說,如果a == 0然後a and b in s導致0,但如果是a任何其它數量然後a and b in s將導致True如果b是在s,而且會導致在False如果b不在s。請參閱我對Assigning string with boolean expression的回答以獲取更多信息(包含衆多示例)。