我在Python中遇到了gcd的这种实现:
def gcd(x,y): return y and gcd(y, x % y) or x
我不明白布尔值在返回时是如何工作的?在解释器中尝试了一些数字后,我注意到and
总是返回右边的数字,而or
返回左边的数字。为什么是这样?另外,您可以一步一步地通过简单调用此函数来指导我,以便了解正在发生的事情吗?
答案 0 :(得分:5)
这是因为and
和or
运算符在Python中的评估方式。
表达式
x and y
首先评估x
;如果x
为false,则返回其值;否则,将评估y
并返回结果值。表达式
x or y
首先评估x
;如果x
为真,则返回其值;否则,将评估y
并返回结果值。
他们不会返回True
或False
,他们会返回最后一个评估值,这就是为什么我们可以编写类似的内容 -
s = s or "Some default value"
默认s
的值None
或空字符串或空列表,或0。
基本上,or
返回第一个非类似false的值(其中类似false的值为0,或None或Empty string / list / tuple等)或者如果所有值都返回最后一个类似false的值是虚假的。示例 -
In [1]: 0 or 10
Out[1]: 10
In [2]: 5 or 0 or 10
Out[2]: 5
In [7]: 0 or '' or [] or ()
Out[7]: ()
并且,如果所有值都是真的,and
将返回第一个类似虚假的值或最后一个类似真值的值。示例 -
In [3]: 0 and 10
Out[3]: 0
In [4]: 5 and 10
Out[4]: 10
In [6]: 5 and 0 and 10
Out[6]: 0
在您的情况下,它的作用是 -
如果y
为0则返回x(与x的值无关)。
否则计算gcd(y, x%y)
如果非零则返回它。 (虽然它永远不会是0
)
如果gcd(y, x%y)
的结果为0,则返回x
。
答案 1 :(得分:1)
这称为"短路。"每当Python知道布尔表达式的结果是什么时,它就会停止评估。这是一个优化,但它也提供了一些方便的习语,比如分配默认值。
def do_a_thing(maybelist=None):
# this is done all the time when you want the default argument to be
# a list, but you don't want to make the mistake of a mutable default argument
maybelist = maybelist or []
您提供的实施示例让那些不了解Euclid's Algorithm计算gcd的人感到困惑,因为它实际上计算gcd的方式并不明显。我想说这是一个滥用短路评估的例子。
答案 2 :(得分:1)
在Python中,默认为False的唯一整数为零。正如其中一条评论所说,逻辑值会执行短路。
声明:
a and b
如果'a'的计算结果为False,那么'b'不需要进行评估,因此表达式的结果为'a',但如果'a'的计算结果为True,那么b
仍然需要要进行评估,因此b
将是表达式的结果,除非a
求值为False。
`或'相反的方式,如果你考虑它就有意义。
答案 3 :(得分:0)
and
和or
在Python中不是严格的布尔运算符。 x and y
和x or y
将始终评估为x
或y
,具体取决于"真实性"的价值。假值是数字零,空字符串和空容器;所有其他值都是真的。这意味着
x and y == x
为假,则x
;未评估y
x and y == y
为真,则x
x or y == x
为真,则x
;未评估y
x or y == y
为假,则x
评估实际布尔值的唯一时间是所涉及的x
或y
值是实际布尔值。