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也会在评估者完成后立即放弃生成事物。 因为这个原因,所有的内存都会消耗大量的内存并且花费很长时间,而任何内存只会使用几个字节并且立即返回。