Python支持短路运算吗?
Python支持布尔表达式中的短路运算吗?
3 个回答
好的。你可以在你的Python解释器里试试下面的内容:
和
>>>False and 3/0
False
>>>True and 3/0
ZeroDivisionError: integer division or modulo by zero
或者
>>>True or 3/0
True
>>>False or 3/0
ZeroDivisionError: integer division or modulo by zero
运算符 and
和 or
的短路行为:
首先,我们定义一个有用的函数,用来判断某个操作是否被执行。这个简单的函数接受一个参数,打印一条消息,然后返回这个输入,内容不变。
>>> def fun(i):
... print "executed"
... return i
...
我们可以在下面的例子中观察到 Python 的短路行为,特别是在 and
和 or
运算符中:
>>> fun(1)
executed
1
>>> 1 or fun(1) # due to short-circuiting "executed" not printed
1
>>> 1 and fun(1) # fun(1) called and "executed" printed
executed
1
>>> 0 and fun(1) # due to short-circuiting "executed" not printed
0
注意:以下值被解释器视为假:
False None 0 "" () [] {}
函数 any()
和 all()
的短路行为:
Python 的 any()
和 all()
函数也支持短路行为。正如文档中所示,它们会按顺序检查序列中的每个元素,直到找到一个结果,可以提前结束评估。下面的例子可以帮助理解这两个函数。
any()
函数检查是否有任何元素为真。一旦遇到一个真值,它就会停止执行并返回真。
>>> any(fun(i) for i in [1, 2, 3, 4]) # bool(1) = True
executed
True
>>> any(fun(i) for i in [0, 2, 3, 4])
executed # bool(0) = False
executed # bool(2) = True
True
>>> any(fun(i) for i in [0, 0, 3, 4])
executed
executed
executed
True
all()
函数检查所有元素是否都为真,一旦遇到一个假值,它就会停止执行:
>>> all(fun(i) for i in [0, 0, 3, 4])
executed
False
>>> all(fun(i) for i in [1, 0, 3, 4])
executed
executed
False
链式比较的短路行为:
此外,在 Python 中
比较可以任意链式连接;例如,
x < y <= z
等同于x < y and y <= z
,但在这种情况下,y
只会被评估一次(不过在x < y
为假时,z
根本不会被评估)。
>>> 5 > 6 > fun(3) # same as: 5 > 6 and 6 > fun(3)
False # 5 > 6 is False so fun() not called and "executed" NOT printed
>>> 5 < 6 > fun(3) # 5 < 6 is True
executed # fun(3) called and "executed" printed
True
>>> 4 <= 6 > fun(7) # 4 <= 6 is True
executed # fun(3) called and "executed" printed
False
>>> 5 < fun(6) < 3 # only prints "executed" once
executed
False
>>> 5 < fun(6) and fun(6) < 3 # prints "executed" twice, because the second part executes it again
executed
executed
False
编辑:
还有一个有趣的点:Python 中的逻辑 and
和 or
运算符返回的是操作数的值,而不是布尔值(True
或 False
)。例如:
操作
x and y
的结果是如果 x 为假,则返回 x,否则返回 y
这与其他语言不同,例如 C 语言中的 &&
和 ||
运算符返回的是 0 或 1。
例子:
>>> 3 and 5 # Second operand evaluated and returned
5
>>> 3 and ()
()
>>> () and 5 # Second operand NOT evaluated as first operand () is false
() # so first operand returned
同样,or
运算符返回的是最左边的值,只要 bool(value)
为 True
,否则返回最右边的假值(根据短路行为),例子如下:
>>> 2 or 5 # left most operand bool(2) == True
2
>>> 0 or 5 # bool(0) == False and bool(5) == True
5
>>> 0 or ()
()
那么,这有什么用呢?下面的例子来自 《实用 Python》 由 Magnus Lie Hetland 著:
假设用户需要输入他的名字,但也可以选择不输入,这种情况下你想使用默认值 '<Unknown>'
。
你可以使用 if 语句,但也可以更简洁地表达:
In [171]: name = raw_input('Enter Name: ') or '<Unknown>'
Enter Name:
In [172]: name
Out[172]: '<Unknown>'
换句话说,如果 raw_input
的返回值为真(不是空字符串),那么就将其赋值给 name(没有变化);否则,默认值 '<Unknown>'
将被赋值给 name
。
没错,and
和 or
这两个操作符都是短路的——你可以查看文档了解更多。