2010-08-25 16 views
12

如果我做的:Python的reduce()短路嗎?

result = reduce(operator.and_, [False] * 1000) 

將它的第一個結果後停止? (因爲False & anything == False

類似地:

result = reduce(operator.or_, [True] * 1000) 

回答

21

它沒有。您的替代方案是anyall

result = reduce(operator.and_, [False] * 1000) 
result = reduce(operator.or_, [True] * 1000) 

可以通過

result = all([False] * 1000) 
result = any([True] * 1000) 

其中做短路來替代。

定時結果示區別:

In [1]: import operator 

In [2]: timeit result = reduce(operator.and_, [False] * 1000) 
10000 loops, best of 3: 113 us per loop 

In [3]: timeit result = all([False] * 1000) 
100000 loops, best of 3: 5.59 us per loop 

In [4]: timeit result = reduce(operator.or_, [True] * 1000) 
10000 loops, best of 3: 113 us per loop 

In [5]: timeit result = any([True] * 1000) 
100000 loops, best of 3: 5.49 us per loop 
+0

你說得對。 'any()'和'all()'似乎正是我需要的(也可能更清晰)。你是怎麼做到這個時機的? – 2010-08-25 22:34:30

+1

我正在使用'ipython'及其''timeit'命令。但是Python有一個timeit模塊。因此,您可以從命令行執行'python -mtimeit'result = any([True] * 10)「'進行計時。 – 2010-08-25 22:46:10

5

不僅減少()不短路,它不可能短路過的所有項目被還原,因爲它只考慮的項目2在一次。此外,它不知道使用功能短路的條件。 (如果函數可能有一個屬性表明它們開始短路的值,那麼reduce()就可以識別和使用,但它們不會),這將是非常有趣的。)

+0

這就是Lisp用戶非常喜歡Lisp的原因 - 因爲所有函數都是數據,所以(主要)可以做這種檢測。 – Lucretiel 2015-05-31 00:43:38

3

很可能可能的(見fate of reduce),替代減少的實施將做得很好。

這個想法對我來說是完美的工作,使設計更透明。

def ipairs(seq): 
    prev = None 
    for item in seq: 
     if prev is not None: 
      yield (prev, item) 
     prev = item 

def iapply(seq, func): 
    for a, b in ipairs(seq): 
     yield func(a, b) 

def satisfy(seq, cond): 
    return all(iapply(seq, cond)) 

def is_uniform(seq): 
    return satisfy(seq, lambda a, b: a == b) 

正如你看到減少分成iapply < - ipairs

請注意,它不等同於

def ireduce(seq, func): 
    prev = None 
    for item in seq: 
     if prev is None: 
      prev = item 
     else: 
      prev = func(prev, item) 
    return prev 
2

記住,短路評價並不總是你想要的。出於這個原因,「固定」減少到短路將是一個錯誤。例如,我最近必須在處理django中的表單列表時將all()的使用更改爲reduce()。我想報告任何is_valid()問題,而不僅僅是第一個。

+0

它可以使用關鍵字參數作爲短路標準,其他內建函數可以:reduce(operator.or,mylist,key = lambda x::x <0) – LBarret 2012-01-30 14:39:32