【问题标题】:How do "and" and "or" work when combined in one statement?“and”和“or”组合在一个语句中时如何工作?
【发布时间】:2011-02-04 12:23:19
【问题描述】:

由于某种原因,这个功能让我很困惑:

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

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

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

A)

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

或 B)

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

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

【问题讨论】:

  • @Responders,请参阅我 1 分钟后的更新。对不起。
  • 只记得'and'和'or'语句返回最后一个要计算的表达式。 :)

标签: python boolean-logic if-statement


【解决方案1】:

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

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

x and y 如果x 为真,则返回y,如果x 为假,则xa or b,反之亦然,如果为真则返回a,否则返回b

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

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

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

【讨论】:

  • @Alex +1 感谢您的深入解释。他们显然已经做到了,以至于我在 10 分钟内无法接受答案 :( 但很好的答案。
  • @orokusaki,谢谢,我相信你以后会接受的;-)。
  • +1 用于提及python的三元运算符,更容易阅读/理解恕我直言
  • 我很久以前就学会了使用括号来使解释器/编译器执行希望代码执行的操作,而不是受制于优先级。它有助于为我和任何在我传递代码后维护它的人记录代码。我认为这是防御性编码的一部分。
【解决方案2】:

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

【讨论】:

  • 啊,谢谢伊格纳西奥。在不理解这一点的情况下,我不知道我是如何在 Python 中走到今天的。这是我第一次看到它完全像这样使用。 +1
【解决方案3】:

C and X or Y 是 Python 用户长期尝试代理C ? X : Y

在大多数情况下,除了如果XFalse——这会导致 Python 代码中的许多错误,所以在Python FAQ 中,你会发现更正确的解决方案是(C and [X] or [Y])[0],因为具有单个元素的列表,无论其评估的布尔值如何,始终是True!例如:[None]True,但 None 不是。上面的 OP 示例有效,因为表示 X 的字符串不为空。

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

【讨论】:

    【解决方案4】:

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

    以下是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
    

    更喜欢新的表示法:

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

    【讨论】:

    • @Mark 这是我熟悉的版本,直到今天我才在我的帖子中看到这个版本。 +1
    【解决方案5】:

    您可能想阅读这篇文章The Peculiar Nature of And and Or in Python 中有关 Python 的“和/或技巧”。这有点像 VBA 或 VB 中的 IIF(),或 C 风格语言中的 ?:

    【讨论】:

    • @Abel 谢谢。我刚读了它,有趣的文章。我已经大量使用了return a or b 语法,但由于某种原因,这个 sn-p 不能运行。
    【解决方案6】:

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

    a 和 b -->

    if a:
      return b
    else:
      return a
    

    a 或 b -->

    if a:
      return a
    else:
      return b
    

    【讨论】:

      【解决方案7】:

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

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

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

      总结

      • 它们都返回决定语句结果的第一项。 (在最坏的情况下,序列中的最后一项)

      请注意,此规则也适用于链接的所有“与”或所有“或”语句

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多