python "and" 和 "or" 组合在一个语句中时如何工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2579959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:58:55  来源:igfitidea点击:

How do "and" and "or" work when combined in one statement?

pythonboolean-logicif-statement

提问by orokusaki

For some reason this function confused me:

出于某种原因,这个功能让我感到困惑:

def protocol(port):
    return port == "443" and "https://" or "http://"

Can somebody explain the order of what's happening behind the scenes to make this work the way it does.

有人可以解释一下幕后发生的事情的顺序,以使这项工作按照它的方式工作。

I understood it as this until I tried it:

在我尝试之前,我是这样理解的:

Either A)

要么 A)

def protocol(port):
    if port == "443":
        if bool("https://"):
            return True
    elif bool("http://"):
        return True
    return False

Or B)

或 B)

def protocol(port):
    if port == "443":
        return True + "https://"
    else:
        return True + "http://"

Is this some sort of special case in Python, or am I completely misunderstanding how statements work?

这是 Python 中的某种特殊情况,还是我完全误解了语句的工作原理?

回答by Alex Martelli

It's an old-ish idiom; inserting parentheses to show priority,

这是一个古老的习语;插入括号以显示优先级,

(port == "443" and "https://") or "http://"

x and yreturns yif xis truish, xif xis falsish; a or b, vice versa, returns aif it's truish, otherwise b.

x and y返回y如果x是truish,x如果x是falsish; a or b,反之亦然,a如果为真则返回,否则返回b

So if port == "443"is true, this returns the RHS of the and, i.e., "https://". Otherwise, the andis false, so the orgets into play and returns `"http://", itsRHS.

因此,如果port == "443"为真,则返回 的 RHS and,即"https://"。否则,and是假的,所以or开始发挥作用并返回`"http://",它的RHS。

In modern Python, a better way to do translate this old-ish idiom is:

在现代 Python 中,翻译这个老式习语的更好方法是:

"https://" if port == "443" else "http://"

回答by Ignacio Vazquez-Abrams

andreturns the right operand if the left is true. orreturns the right operand if the left is false. Otherwise they both return the left operand. They are said to coalesce.

and如果左侧为真,则返回右侧操作数。or如果左侧为假,则返回右侧操作数。否则它们都返回左操作数。据说它们会合并

回答by wescpy

C and X or Yis the long-running early attempt by Python users to proxy for C ? X : Y

C and X or Y是 Python 用户为代理而进行的长期早期尝试 C ? X : Y

For the most part it works, exceptif Xis False-- this has led to many bugs in Python code, so in the Python FAQ, you'll find the more correct solution being (C and [X] or [Y])[0]because a list with a single element, regardless of its evaluated Boolean value, is always True! For example: [None]is Truebut Noneisn't. The OP's example above works because the string representing Xis not empty.

对于它的工作原理,在大多数情况下,除了如果XFalse-这导致了Python代码许多错误,因此在Python的常见问题,你会发现更多的正确的解决方案是(C and [X] or [Y])[0]因为有一个单一的元素,不管其评估布尔名单价值,永远是True!例如:[None]TrueNone不是。上面的 OP 示例有效,因为表示的字符串X不为空。

However, all this changed in Python 2.5, when the ternary or conditional operator was added to the language, allowing you to use the cleaner X if C else Yas stated in other posts here. If you see code using the older format, it's because the user has been a long time Python programmer who hasn't adopted the new syntax yet, they cut-n-paste other old code, or their employer is still using 2.4.x (or earlier releases), etc.

然而,这一切在 Python 2.5 中发生了变化,当三元或条件运算符添加到语言中时,允许您使用X if C else Y此处其他帖子中所述的清洁器。如果您看到使用旧格式的代码,那是因为用户是长期未采用新语法的 Python 程序员,他们剪切和粘贴其他旧代码,或者他们的雇主仍在使用 2.4.x (或更早的版本)等。

回答by Mark Byers

This is an ugly hack that is not recommended. It works because of the short-circuiting behaviour of andand orand that they return the one of their arguments rather than a boolean value. Using this technique gives a risk of introducing hard-to-find bugs, so don't use it in new code.

这是一个不推荐的丑陋黑客。它之所以有效是因为andand的短路行为,并且or它们返回它们的参数之一而不是布尔值。使用这种技术有引入难以发现的错误的风险,所以不要在新代码中使用它。

Here's an example of how the and/oridiom can give an unexpected result:

下面是这个and/or习语如何产生意想不到的结果的例子:

>>> foo = 'foobar'
>>> bar = 'foobar'
>>> x = 0
>>> y = 1
>>> (foo == bar) and x or y   # Will this return the value of x if (foo == bar)?
1

Prefer instead the newer notation:

更喜欢新的符号:

return "https://" if port == "443" else "http://"

回答by Abel

You may want to read up on the "and / or trick" of Python in this article The Peculiar Nature of And and Or in Python. It's a bit like the IIF()in VBA or VB, or ?:in C-style languages.

您可能想在这篇文章 Python 中And 和 Or 的特殊性质 中阅读 Python 的“和/或技巧” 。它有点像IIF()在 VBA 或 VB 中,或者?:在 C 风格的语言中。

回答by Yaroslav

This construction works because it 'unfolds' to the following code:

这种构造有效,因为它“展开”为以下代码:

a and b -->

a 和 b -->

if a:
  return b
else:
  return a

a or b -->

a 或 b -->

if a:
  return a
else:
  return b

回答by Zhenhua

With all the good answers, I found these statements help me remember this better and fit how my brain works (and hopefully for for some more out there) :

有了所有好的答案,我发现这些陈述可以帮助我更好地记住这一点,并适合我的大脑工作方式(希望还有更多):

  • “and" returns the first False item (e.g., None, “”, [], (), {}, 0) or the last item if none (e.g. no False found)

  • “or" returns the first True item or the last item (e.g. no True found)**

  • “and”返回第一个 False 项(例如,None、“​​”、[]、()、{}、0)或最后一项,如果没有(例如未找到 False)

  • “或”返回第一个 True 项目或最后一个项目(例如未找到 True)**

In summary:

总之

  • they all return the first item that decides the outcome of the statement. (In the worst case, the last item in the sequence)
  • 它们都返回决定语句结果的第一项。(在最坏的情况下,序列中的最后一项)

Note this rule also applies to a chained all "and" or all "or" statement

请注意,此规则也适用于链式全“和”或全“或”语句