Python 布尔表达式 and or

发布于 2024-09-08 10:09:38 字数 199 浏览 10 评论 0原文

在 python 中,如果你编写类似

foo==bar and spam or eggs

python 的东西,如果布尔语句为真,则返回垃圾邮件,否则返回鸡蛋。有人可以解释这种行为吗?为什么表达式不像一个长布尔值那样被计算?

编辑:具体来说,我试图找出“垃圾邮件”或“鸡蛋”作为表达式结果返回的机制。

In python if you write something like

foo==bar and spam or eggs

python appears to return spam if the boolean statement is true and eggs otherwise. Could someone explain this behaviour? Why is the expression not being evaluated like one long boolean?

Edit: Specifically, I'm trying to figure out the mechanism why 'spam' or 'eggs' is being returned as the result of the expression.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风柔一江水 2024-09-15 10:09:38

运算符 andor 是短路运算符,这意味着如果可以通过仅计算第一个操作数来推导出表达式的结果,则不会计算第二个操作数。例如,如果您有表达式 a 或 b 并且 a 的计算结果为 true,那么 b 的结果是什么并不重要表达式为 true,因此不计算 b。它们实际上的工作原理如下:

  • a 和 b:如果 a 为 false,则不计算 b 并返回 a,否则返回 b。
  • a 或 b:如果 a 为真,则不计算 b 并返回 a,否则返回 b。

Falsey 和 true 是指在布尔上下文中计算结果为 false 或 true 的值。

然而,这个 and/or 习语在当时没有更好的选择的时候很有用,但现在有更好的方法:

spam if foo==bar else eggs

and/or 习语的问题(除了让初学者感到困惑之外)是它给出了错误的结果如果条件为真,但垃圾邮件计算结果为假值(例如空字符串),则结果。因此你应该避免它。

The operators and and or are short-circuiting which means that if the result of the expression can be deduced from evaluating only the first operand, the second is not evaluated. For example if you have the expression a or b and a evaluates to true then it doesn't matter what b is, the result of the expression is true so b is not evaluated. They actually work as follows:

  • a and b: If a is falsey, b is not evaluated and a is returned, otherwise b is returned.
  • a or b: If a is truthy, b is not evaluated and a is returned, otherwise b is returned.

Falsey and truthy refer to values that evaluate to false or true in a boolean context.

However this and/or idiom was useful back in the days when there was no better alternative, but now there is a better way:

spam if foo==bar else eggs

The problem with the and/or idiom (apart from it being confusing to beginners) is that it gives the wrong result if the condition is true but spam evaluates to a falsey value (e.g. the empty string). For this reason you should avoid it.

同展鸳鸯锦 2024-09-15 10:09:38

这就是 Python 布尔运算符的工作原理。

来自 文档 (最后一段解释了为什么它是一个好主意,操作员按照他们的方式工作):

在布尔运算的上下文中,
并且当表达式被使用时
控制流语句,如下
值被解释为 false:
False、全部数字零
类型和空字符串和
容器(包括字符串、元组、
列表、字典、集合和
冻结集)。所有其他值都是
解释为真。 (参见
__nonzero__() 特殊方法来改变这一点。)

如果运算符 not 产生 True
参数为 false,否则 False

表达式x和y首先计算
x;如果 x 为 false,则其值为
返回;否则,计算 y
并返回结果值。

表达式x或y首先计算
x;如果 x 为 true,则其值为
返回;否则,计算 y
并返回结果值。

(请注意,andor 都不限制
他们返回的值和类型
FalseTrue,而是返回
最后评估的参数。这是
有时很有用,例如,如果 s
应替换为的字符串
默认值,如果为空,则
表达式 s 或 'foo' 产生
期望值。因为必须
无论如何,发明一个值,它不会
费心返回相同的值
type 作为其参数,因此例如 not 'foo' 产生 False,而不是 ''。)

This is how the Python boolean operators work.

From the documentation (the last paragraph explains why it is a good idea that the operators work the way they do):

In the context of Boolean operations,
and also when expressions are used by
control flow statements, the following
values are interpreted as false:
False, None, numeric zero of all
types, and empty strings and
containers (including strings, tuples,
lists, dictionaries, sets and
frozensets). All other values are
interpreted as true. (See the
__nonzero__() special method for a way to change this.)

The operator not yields True if its
argument is false, False otherwise.

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.

(Note that neither and nor or restrict
the value and type they return to
False and True, but rather return the
last evaluated argument. This is
sometimes useful, e.g., if s is a
string that should be replaced by a
default value if it is empty, the
expression s or 'foo' yields the
desired value. Because not has to
invent a value anyway, it does not
bother to return a value of the same
type as its argument, so e.g., not 'foo' yields False, not ''.)

深巷少女 2024-09-15 10:09:38

原因是 Python 使用所涉及变量的实际值来计算布尔表达式,而不是将它们限制为 TrueFalse 值。以下值被视为 false:

  • None
  • False
  • 任何数字类型的 0
  • 空序列或集合 ('', ()[]{})
  • 使用 __nonzero__()__len__() 的用户定义类型> 返回 0 或 False 的方法

请参阅 有关详细信息,请参阅 Python 文档的真值测试部分。尤其:

具有布尔结果的运算和内置函数始终返回 0False (对于 false)和 1True< /code> 为 true,除非另有说明。 (重要的例外:布尔运算 orand 始终返回其操作数之一。)


The reason is that Python evaluates boolean expression using the actual values of the variables involved, instead of restricting them to True and False values. The following values are considered to be false:

  • None
  • False
  • 0 of any numeric type
  • empty sequence or set ('', (), [], {})
  • user-defined types with __nonzero__() or __len__() method that returns 0 or False

See the Truth Value Testing section of the Python documentation for more information. In particular:

Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated. (Important exception: the Boolean operations or and and always return one of their operands.)

只为守护你 2024-09-15 10:09:38

尝试使用括号使表达式不含糊。就这样,你会得到:

(foo == bar and spam) or eggs

Try using parentheses to make the expression non-ambiguous. The way it is, you're getting:

(foo == bar and spam) or eggs
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文