尝试理解"any([comprehension])"和"any(comprehension)"之间的区别

3

以下两个表达方式有何不同:

if any([value % 2 for value in values]):
    print('done')

并且

if any(value % 2 for value in values):
    print('done')

其中values是一个0-20范围内的数组吗?

我知道any()函数会检查数组中的任何值是否符合要求,但我想知道这两个函数之间是否有任何区别。


顺便提一下,您需要指定一个条件,例如 value % 2 == 0 - imM4TT
2
@imM4TT 不,这不是必要的。 - Walter Tross
在这种情况下有点令人困惑,没有明确的语句它实际上正在寻找奇数。 - imM4TT
2个回答

9
第一个函数先计算整个列表,再应用any函数。另一方面,第二个函数是“懒惰”的;如果某个元素为真,any函数会立即返回True,而不会继续计算其余的元素。
def foo(x):
    print(f"foo({x}) is called!")
    return x >= 5

print(any([foo(x) for x in range(10)]))
# foo(0) is called!
# foo(1) is called!
# foo(2) is called!
# foo(3) is called!
# foo(4) is called!
# foo(5) is called!
# foo(6) is called!
# foo(7) is called!
# foo(8) is called!
# foo(9) is called!
# True

print(any(foo(x) for x in range(10)))
# foo(0) is called!
# foo(1) is called!
# foo(2) is called!
# foo(3) is called!
# foo(4) is called!
# foo(5) is called!
# True

如您所见,第二个示例中并未对 x > 5 进行 foo(x) 的计算,因为由于使用 any ,已经找到了 foo(5) == True的结果,这足以说明结果是 True


第一个的时间复杂度是O(n),而第二个的时间复杂度是O(1),这样说是否公平? - user17775845
1
不一定 - 它可能会一直执行到找到第一个“Truth”。 - Daniel Hao

5
两者的区别在于,第一个从`values`中构建了一个临时列表,然后将其传递给any()函数(然后删除它)。第二个则使用所谓的生成器表达式,它会按需迭代计算并逐个产生结果,并将它们传递给any()函数。由于any()函数的工作方式,它可能会在满足条件前就停止迭代。对于非常大的数据集,后者需要更少的内存才能完成(如果提前停止,还可能需要更少的处理器时间)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接