我正在编写一个脚本,我必须根据许多条件测试数字。如果满足任何条件,我想返回True
,我希望以最快的方式做到这一点。
我的第一个想法是使用any()
代替嵌套if
语句或多个or
链接我的条件。因为如果任何条件是True
我会感到满意,我可以真正受益于any()
懒惰并尽快返回True。
基于以下事实:以下打印是立即发生的,而不是在10(= 0 + 1 + 2 + 3 + 4)秒之后,我认为是。是这样的,还是我错了?
import time
def some(sec):
time.sleep(sec)
return True
print(any(some(x) for x in range(5)))
答案 0 :(得分:15)
是,any()
和all()
短路,一旦结果明确就中止:请参阅docs:
所有(迭代)强>
如果iterable的所有元素都为真(或者如果是),则返回True iterable是空的)。相当于:
def all(iterable): for element in iterable: if not element: return False return True
<强>任何(迭代)强>
如果iterable的任何元素为true,则返回True。如果是可迭代的 空,返回False。相当于:
def any(iterable): for element in iterable: if element: return True return False
答案 1 :(得分:6)
all()
和any()
函数在第一个&#34; true&#34;上发生短路。可迭代的元素,可迭代本身可以以非惰性方式构造。考虑这个例子:
>> any(x == 100 for x in range(10**8))
True
这需要几秒钟才能在Python 2中执行,因为range(10**8)
构造了一个包含10 ** 8个元素的列表。同样的表达式在Python 3中立即运行,其中range()
是懒惰的。
答案 2 :(得分:4)
正如Tim正确提到的那样,any
和all
会发生短路,但在您的代码中, lazy 的原因是使用了generators。例如,以下代码不会是惰性的:
print(any([slow_operation(x) for x in big_list]))
列表将完全构建和计算,然后作为参数传递给any
。
生成器是可按需计算每个项目的迭代器。它们可以是expressions,functions,有时也可以手动实现为惰性iterators。
答案 3 :(得分:2)
是的,如下所示,它很懒惰:
JavaPairRDD<String, Iterable<String>> pairRDD = ...;
JavaPairRDD<String, Map<String, Integer>> resultPairRDD = pairRDD.mapValues(new Function<Iterable<String>, Map<String, Integer>>() {
@Override
public Map<String, Integer> call(Iterable<String> arg0) throws Exception {
Map<String, Integer> countMap = new HashMap<String, Integer>();
for(String s:arg0){
int curCnt = countMap.containsKey(s) ? countMap.get(s) : 0;
countMap.put(s, (curCnt+1));
}
return countMap;
}
});
在测试第一项后第一次运行def some(x, result=True):
print(x)
return result
>>> print(any(some(x) for x in range(5)))
0
True
>>> print(any(some(x, False) for x in range(5)))
0
1
2
3
4
False
停止,即它使评估短路。
在第二轮中any()
继续测试,直到序列耗尽。
答案 4 :(得分:2)
是的,这是一个实验,它比你的计时实验更明确地显示它:
import random
def some(x):
print(x, end = ', ')
return random.random() < 0.25
for i in range(5):
print(any(some(x) for x in range(10)))
典型的运行:
0, 1, 2, True
0, 1, True
0, True
0, 1, 2, 3, True
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, False
答案 5 :(得分:0)
不。 All和Any支持短路,但它们不会使条件解释变得懒惰。
如果您希望使用惰性评估来计算All或Any,则需要向他们传递一个生成器。否则,值会在构建列表/集合/迭代器/任何内容的那一刻被评估
答案 6 :(得分:0)
JoshiRaez 是真正的正确答案。
这是一个例子
a = []
any([True, a[0]])
会失败
另一方面,使用 OR(或 AND)不会失败,因为它不是函数:
a = []
True or a[0]