Python是否会懒惰地评估它的条件?

例如,如果我有以下陈述:

if( foo1 or foo2) ... ... 

如果foo1是真的,python会检查foo2的条件吗?

是的,Python会懒惰地评估布尔条件。

文件说 ,

expression式x和y首先评估x; 如果x为假,则返回其值; 否则,评估y并返回结果值。

expression式x或y首先评估x; 如果x为真,则返回其值; 否则,评估y并返回结果值。

Python的懒惰可以通过下面的代码来certificate:

 def foo(): print('foo') return False def bar(): print('bar') return False foo() and bar() #Only 'foo' is printed 

另一方面,

 foo() or bar() 

会导致'foo'和'bar'被打印。

这不是技术上懒惰的评估,它是短路布尔expression式。

懒惰的评价有一个不同的内涵。 例如,真正的懒惰评估可能会允许这样做

 def foo(arg) : print "Couldn't care less" foo([][0]) 

但是Python不。

Python也很好,因为它“回声”它是布尔参数。 例如,一个or条件返回它的第一个“truthy”参数或最后一个参数(如果所有参数都是“falsey”)。 一个和条件是相反的。

所以“回声论证”是布尔的意思

2和[]和1

评估为[]和

[]或1或2

评估为1

and or懒惰的

& | 不是懒惰的

是的,Python懒惰地评估,所以foo2不会被检查。

如果我不知道密钥是否存在,我总是使用它来从类似字典的对象中获取项目:

 if 'key' in mydict and mydict['key'] == 'heyyo!': do_stuff() 

请参阅@ unutbu的答案以获得更全面的解释。

它真的是短路的一部分:

 >>> 1 or 1/0 #also 0 and 1/0 1 >>> 0 or 1/0 #also 1 and 1/0 Traceback (most recent call last): File "<pyshell#1240>", line 1, in <module> 0 or 1/0 ZeroDivisionError: integer division or modulo by zero 

一个简短的演示将是比较两者之间的时间差异

 all(xrange(1,1000000000)) 

 any(xrange(1,1000000000)) 

all()必须检查每个值,而any()可以放弃第一个True被find之后。 因此,作为生成器的xrange也会在评估者完成后立即放弃生成事物。 因为这个原因,所有的内存都会消耗大量的内存并且花费很长时间,而任何内存只会使用几个字节并且立即返回。