所有(列表)都使用短路评估吗?

时间:2013-06-22 01:12:30

标签: python evaluation short-circuiting

我希望使用Python all()函数来帮助我计算某些内容,但如果all()在点击False后没有进行评估,则可能会花费更长的时间。我想它可能是短路评估,但我只是想确定。另外,有没有办法告诉Python如何评估函数?

4 个答案:

答案 0 :(得分:14)

是的,它短路:

>>> 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为假时,函数会立即中断。

答案 1 :(得分:3)

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

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

当条件变为false时,当x到达列表中的1时,上述停止。如果all没有短路,那么当x达到0时,我们会得到除零。

答案 2 :(得分:0)

在回答您是否可以告诉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

答案 3 :(得分:0)

确保你没有像我最初那样做,试图在调用之前尝试使用短路来测试方法的存在:

>>> 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'

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

False

在第一个代码片段中,Python在将列表传递给all()之前对列表进行求值,因此它仍会抛出异常。这与使用list()强制所有()不使用晨星答案中的短路评估基本相同