数字在 Python 中的布尔值

Booleans with numbers in Python

我在 Python 中遇到了这个 gcd 实现:

def gcd(x,y): return y and gcd(y, x % y) or x

我不明白布尔值在 return 中是如何工作的?在解释器中尝试了一些数字后,我注意到 and 总是 return 右边的数字,而 or return 左边的数字。为什么是这样?另外,您能否逐步引导我简单调用此函数,以便我了解发生了什么?

这叫做 "short circuiting." 只要 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 的并不明显。我会说这是有人滥用短路评估的一个例子。

在 Python 中,唯一默认为 False 的整数是零。正如评论之一所说,逻辑值执行短路。

用语句:

a and b

如果 'a' 的计算结果为 False,则 'b' 不需要计算,因此表达式的结果为 'a',但如果 'a' 的计算结果为True,那么 b 仍然需要计算,所以 b 将是表达式的结果,除非 a 计算为 False。

`or' 以相反的方式工作,如果您考虑一下,这是有道理的。

这是因为 andor 运算符在 Python 中的计算方式。

来自 documentation -

The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

它们不是 return TrueFalse ,它们 return 最后评估的值,这就是为什么我们可以写 -

s = s or "Some default value"

如果 None 或空字符串或空列表,或 0,则默认 s 的值。


基本上,or return 是第一个非类假值(其中类假值是 0,或 None 或空 string/list/tuple,等等)或者如果所有值都是类假值,则最后一个类假值。例子-

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 return 是第一个类假值,或者最后一个类真值,如果所有值都类真的话。例子-

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

在你的情况下,它的工作原理是 -

  1. 如果y为0则returns x(不考虑x的值).

  2. 否则它会计算 gcd(y, x%y) 如果它是非零的 return。 (虽然它永远不会是 0

  3. 如果gcd(y, x%y)的结果是0,那么returns x .

andor 在 Python 中不是严格的布尔运算符。 x and yx or y 将始终评估为 xy,具体取决于值的 "truthiness"。假值是数字零、空字符串和空容器;所有其他值都为真。这意味着

  • x and y == x 如果 x 为假; y 未评估
  • x and y == y 如果 x 为真
  • x or y == x 如果 x 为真; y 未评估
  • x or y == y 如果 x 为假

唯一一次评估为实际布尔值是当涉及的 xy 值是实际布尔值时。