例如,如果我有以下陈述:
if( foo1 or foo2)
...
...
如果foo1为真,Python会检查foo2的条件吗?例如,如果我有以下陈述:
if( foo1 or foo2)
...
...
如果foo1为真,Python会检查foo2的条件吗?是的,Python对布尔条件进行惰性求值。
文档说:
表达式 x and y 首先对 x 进行求值;如果 x 为 false,则返回其值;否则,对 y 进行求值并返回结果值。
表达式 x or y 首先对 x 进行求值;如果 x 为 true,则返回其值;否则,对 y 进行求值并返回结果值。
and
和or
是惰性求值的。
&
和|
不是惰性求值的。
以下代码可以证明Python的惰性:
def foo():
print('foo')
return False
def bar():
print('bar')
return False
foo() and bar() #Only 'foo' is printed
另一方面,
foo() or bar()
会导致'foo'和'bar'都被打印出来。
这并不是严格的惰性求值,而是短路布尔表达式。
懒惰求值有着稍微不同的内涵。例如,真正的惰性求值可能会允许这样做:
def foo(arg) :
print "Couldn't care less"
foo([][0])
但是 Python 不会。
Python 在布尔参数方面也很好用。例如,一个 or 条件返回它的第一个“真值”参数或最后一个参数(如果所有参数都是“假值”)。而 and 条件则相反。
因此,“回声参数”布尔值意味着
2 and [] and 1
计算结果为 [],而
[] or 1 or 2
计算结果为 1。
all(xrange(1,1000000000))
any(xrange(1,1000000000))
all()函数需要检查每一个数值,而any()函数在找到第一个True后就可以停止了。由于xrange是一个生成器,因此当求值器完成时,它也会停止生成东西。因此,all()函数将消耗大量RAM并花费很长时间,而any()函数只使用几个字节并立即返回。
是的,Python使用惰性求值,因此不会检查 foo2
。
如果我不知道键是否存在,我会经常使用这个功能从类似字典的对象中获取项目:
if 'key' in mydict and mydict['key'] == 'heyyo!':
do_stuff()
if mydict.get("key") == 'heyyo!':
也可以工作 - .get
如果找不到键,则会返回 None
(或指定的默认值)。 - DSM.get
方法。 - jdotjdotif mydict.get("key"):
,因为None
会被视为False
。 - jdotjdot'heyyo!'
的比较。 - DSM实际上被短路的是or
部分:
>>> 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
help("or")
。 在这种情况下,请阅读第四段。 - DSMif
”无关,而与“or
”有关。 - jwodder