当在一个陈述中合并时,“和”和“或”如何工作?

时间:2010-04-05 17:47:39

标签: python boolean-logic if-statement

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

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中的某种特殊情况,还是我完全误解了语句的工作原理?

7 个答案:

答案 0 :(得分:24)

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

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

x and y如果y真实,则返回xx如果x是假的,则返回a or b; a,反之亦然,如果它是真的,则返回b,否则port == "443"

因此,如果and为真,则返回"https://"的RHS,即and。否则,or为false,因此"https://" if port == "443" else "http://" 开始播放并返回“”http://“, RHS。

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

{{1}}

答案 1 :(得分:8)

如果左边为真,

and返回右操作数。如果左边为假,则or返回右操作数。否则它们都返回左操作数。他们被称为合并

答案 2 :(得分:5)

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(或早期版本)等。

答案 3 :(得分:2)

这是一个丑陋的黑客,不推荐。它起作用的原因是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://"

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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

a和b - >

if a:
  return b
else:
  return a

a或b - >

if a:
  return a
else:
  return b

答案 6 :(得分:0)

有了所有好的答案,我发现这些陈述可以帮助我更好地记住这一点,并使我的大脑工作得很好(并希望在那里有更多的东西):

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

    < / LI>
  • “或”返回第一个True项目或最后一个项目(例如找不到True)**

总结

  • 他们都返回决定声明结果的第一个项目。 (在最坏的情况下,序列中的最后一项)

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