例如,如果我有以下语句:
if( foo1 or foo2)
...
...
如果 foo1 为真,python 会检查 foo2 的条件吗?
是的,Python 懒惰地评估布尔条件。
文档说,
表达式 x 和 y 首先计算 x;如果 x 为假,则返回其值;否则,评估 y 并返回结果值。
表达式 x 或 y 首先计算 x;如果 x 为真,则返回其值;否则,评估 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 条件返回它的第一个“真”参数或最后一个参数(如果所有参数都是“假的”)。与条件相反。
所以“回声参数”布尔值意味着
2 和 [] 和 1
计算为 [],并且
[] 或 1 或 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()
请参阅@unutbu 的答案以获得更全面的解释。
确实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