2012-12-06 90 views
2

任何人都可以解釋爲什麼在python內建builder中all返回True在這種情況下all([])空列表的所有內置函數

In [33]: all([]) 
Out[33]: True 

In [34]: all([0]) 
Out[34]: False 

In [35]: __builtins__.all([]) 
Out[35]: True 
+0

'all(l)'相當於'l [0]和l [1]和...',沒有東西的''和'是真的。 – katrielalex

+0

http://en.wikipedia.org/wiki/Empty_domain – katrielalex

回答

6

我不相信任何其他的答案確實解決了這個問題,爲什麼這應該是這樣的。

Python的all()的定義來自布爾邏輯。例如,如果我們說「所有天鵝都是白色的」,那麼一隻黑天鵝就會駁斥這種說法。然而,如果我們說「所有獨角獸都是粉紅色的」,邏輯學家會認爲這是一個真實的陳述,因爲沒有非粉紅色的獨角獸。換句話說,「全部」是vacuously true

實際上它給了我們一個有用的不變量。如果all(A)all(B)都是真的,那麼all(A + B)的組合也是正確的。如果all({})是錯誤的,我們應該有一個不太有用的情況,因爲將兩個表達式中的一個錯誤突然結合給出了意想不到的真實結果。

因此,Python需要從布爾邏輯中獲取all([]) == True,並與其他具有類似構造的語言保持一致。

把它放回到Python中,在很多情況下,空洞的事實使得算法更簡單。例如,如果我們有一棵樹並且想要驗證所有節點,那麼我們可以說節點是有效的,只要它滿足一些條件並且它的所有子節點都是有效的。在all()的備選定義中,這變得更加複雜,因爲如果它符合條件並且沒有孩子或其所有孩子都有效,那麼它就是有效的。

class Node: 
    def isValid(self): 
     return some_condition(self) and all(child.isValid for child in self.children) 
+1

很好的解釋。我會補充幾句關於「任何」的話,爲什麼「一些獨角獸是粉紅色的」是錯誤的。 – georg

2

docs

返回真,如果迭代的所有元素都是真(或者,如果可迭代爲空)。

所以,粗略地說,它是這樣定義的。

讓您可以通過使用

list = [] 
if list and all(list): 
    pass 
2

As the docs sayall相當於:

def all(iterable): 
    for element in iterable: 
     if not element: 
      return False 
    return True 

對於空iterable永遠不會執行循環體,所以立即返回True

0

此另一種解釋是allany是二元操作andor有關參數任意長的數的概括。因此,allany可以如定義:

def all(xs): 
    return reduce(lambda x,y: x and y, xs, True) 

def any(xs): 
    return reduce(lambda x,y: x or y, xs, False) 

TrueFalse參數表明all([]) == Trueany([]) == False

not all(iterable) 
# is the same as: 
any(not x for x in iterable) 

和對稱

not any(iterable) 
# is the same as: 
all(not x for x in iterable) 

這些規則要求all([]) == True

0

all任何表達可以通過any反之亦然被重寫。


功能all是可讀的非常有用的斷言:

assert all(required_condition(x) for x in some_results_being_verified) 

(也不是那麼壞,如果一個任務有沒有結果,但是如果所有的結果都是不正確的東西是很破。)

相關問題