我希望使用Python all()
函数来帮助我计算某些内容,但如果all()
在点击False
后没有进行评估,则可能会花费更长的时间。我想它可能是短路评估,但我只是想确定。另外,有没有办法告诉Python如何评估函数?
答案 0 :(得分:14)
是的,它短路:
>>> def test():
... yield True
... print('one')
... yield False
... print('two')
... yield True
... print('three')
...
>>> all(test())
one
False
如果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()强制所有()不使用晨星答案中的短路评估基本相同