Python的all函数使用短路求值吗?

vyswwuz2  于 2023-11-16  发布在  Python
关注(0)|答案(4)|浏览(95)

我想使用Python的all()函数来帮助我计算一些东西,但是如果all()在遇到False时没有立即求值,那么这个东西可能需要更长的时间。我想它可能是短路求值的,但我只是想确定一下。还有,在Python中有没有一种方法来告诉函数是如何求值的?

    • 编者按**:因为anyall函数,所以它们的参数必须在调用之前进行求值。这通常会造成没有短路的印象-但它们仍然会短路。要解决这个问题,请传递一个 * 生成器表达式 *,或其他延迟求值的表达式,而不是序列。有关详细信息,请参阅Lazy function evaluation in any() / all()
yr9zkbsy

yr9zkbsy1#

是的,它会短路:

>>> def test():
...     yield True
...     print('one')
...     yield False
...     print('two')
...     yield True
...     print('three')
...
>>> all(test())
one
False

字符串
从docs:
如果 iterable 的所有元素都为true(或者iterable为空),则返回True。等效于:

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


因此,当return为False时,函数立即中断。

eivnm1vs

eivnm1vs2#

是的,all确实使用短路评估。例如:

all(1.0/x < 0.5  for x in [4, 8, 1, 0])
=> False

字符串
x到达列表中的1时,上面的操作停止,此时条件变为false。如果all没有短路,那么当x到达0时,我们会得到一个除以零的结果。

jei2mxaa

jei2mxaa3#

请确保您不要像我最初所做的那样,在调用方法之前尝试使用短路来测试方法的存在:

>>> class MyClass(object):
...    pass
... 
>>> a = MyClass()
>>> all([hasattr(a, 'b'), a.b()])
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'b'

字符串

>>> hasattr(a, 'b') and a.b()  # doesn't evaluate a.b() as hasattr(a, 'b') is false
False


在第一个代码片段中,Python在将列表传递给all()之前对其求值,因此它仍然会抛出异常。

bwntbbo3

bwntbbo34#

在回答你是否可以告诉all是否短路评估的问题时,默认情况下它是短路的,但如果你不想它是短路的,你可以这样做:

result = all(list(iterable))

字符串
虽然这可能会有不受欢迎的属性,整个列表将被加载到内存中。我想不出你会如何避免,除了使用一个不同的函数。例如

result = reduce(lambda x,y: x and y, iterable)
result = min(iterable) # surprisingly similar to all; YMMV if iterable contains non-booleans

相关问题