如果我做的:Python的reduce()短路嗎?
result = reduce(operator.and_, [False] * 1000)
將它的第一個結果後停止? (因爲False & anything == False
)
類似地:
result = reduce(operator.or_, [True] * 1000)
如果我做的:Python的reduce()短路嗎?
result = reduce(operator.and_, [False] * 1000)
將它的第一個結果後停止? (因爲False & anything == False
)
類似地:
result = reduce(operator.or_, [True] * 1000)
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
不僅減少()不短路,它不可能短路過的所有項目被還原,因爲它只考慮的項目2在一次。此外,它不知道使用功能短路的條件。 (如果函數可能有一個屬性表明它們開始短路的值,那麼reduce()就可以識別和使用,但它們不會),這將是非常有趣的。)
這就是Lisp用戶非常喜歡Lisp的原因 - 因爲所有函數都是數據,所以(主要)可以做這種檢測。 – Lucretiel 2015-05-31 00:43:38
很可能可能的(見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
記住,短路評價並不總是你想要的。出於這個原因,「固定」減少到短路將是一個錯誤。例如,我最近必須在處理django中的表單列表時將all()的使用更改爲reduce()。我想報告任何is_valid()問題,而不僅僅是第一個。
它可以使用關鍵字參數作爲短路標準,其他內建函數可以:reduce(operator.or,mylist,key = lambda x::x <0) – LBarret 2012-01-30 14:39:32
你說得對。 'any()'和'all()'似乎正是我需要的(也可能更清晰)。你是怎麼做到這個時機的? – 2010-08-25 22:34:30
我正在使用'ipython'及其''timeit'命令。但是Python有一個timeit模塊。因此,您可以從命令行執行'python -mtimeit'result = any([True] * 10)「'進行計時。 – 2010-08-25 22:46:10