“和”如何表达?和“或”合并在一个语句中时有效吗?

发布于 2024-08-27 17:45:25 字数 586 浏览 10 评论 0原文

由于某种原因,这个函数让我感到困惑:

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

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)

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

Or 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?

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

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

发布评论

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

评论(7

从此见与不见 2024-09-03 17:45:25

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

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

如果 x 为真,则 x 和 y 返回 y,如果 x,则返回 x 是虚假的; a 或 b,反之亦然,如果正确则返回 a,否则返回 b

因此,如果 port == "443" 为 true,则返回 的 RHS,即 "https://"。否则,and 为 false,因此 or 发挥作用并返回“http://”, RHS。

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

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

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

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

x and y returns y if x is truish, x if x is falsish; a or b, vice versa, returns a if it's truish, otherwise b.

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

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

"https://" if port == "443" else "http://"
泅渡 2024-09-03 17:45:25

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

and returns the right operand if the left is true. or returns the right operand if the left is false. Otherwise they both return the left operand. They are said to coalesce.

活泼老夫 2024-09-03 17:45:25

您真正要问的是像 C 和 X 或 Y 这样的表达式的含义或作用。这是Python 用户长期运行的早期尝试来代理C 吗? X : Y

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

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

总而言之,解决您的具体问题会带来一个也被使用的“隐藏功能”,所以让我们仔细看看返回端口==“443”和“https://” " 或 "http://"

and 的绑定比 or 更强,这意味着您可以有效地想象此等效表达式中的一对括号:<代码>(端口==“443”和“https://”)或“http://”。此外,我提到的隐藏功能被称为短路,这样如果(端口==“443”和“https://”)都为真(它们确实如此),则< code>or 子句被完全忽略。但是,如果其中一个或都不为真,则这是唯一一次使用 or 子句。

另一个观察结果:非空字符串总是 True,因此 port == "443" 是唯一可能为 False 的东西,所以这是所提出的主要问题。如果为 true,则计算将移至 and 右侧,这意味着返回 "https://"。如果为 false,则会发生另一个短路,其中 "https://" 被跳过,并且评估继续到 or 的右侧。

该代码的底线是:它检查是否 port == "443",如果是,则返回 "https://",否则 <返回代码>“http://”。 TrueFalse 都可能不是返回值。最准确的等价形式是:

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

在现代 Python 中,您可以这样写:

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

最后一个假设是 port 是一个字符串。更强大的版本将支持整数输入,例如,return "https://" if str(port) == "443" else "http://"

What you are really asking is what an expression like C and X or Y means or does. It is the long-running early attempt by Python users to proxy for C ? X : Y

For the most part it works, except if X is 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 True but None isn't. The OP's example above works because the string representing X is not empty.

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 Y as 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.

All that said, addressing your specific question brings up a "hidden feature" that's employed as well, so let's take a closer look at return port == "443" and "https://" or "http://":

The and binds stronger than the or, meaning you can effectively imagine a pair of parentheses in this equivalent expression: (port == "443" and "https://") or "http://". Furthermore, the hidden feature I referred to is known as a short circuit such that if both (port == "443" and "https://") are true (which they are), the or clause is completely ignored. However if one or neither are true, that's the only time the or clause will be used.

Another observation: non-empty strings are always True, so port == "443" is the only thing that can possibly be False, so it is the main question being asked. If it is true, then evaluation moves to the right of the and, meaning "https://" is returned. If it is false, another short circuit happens where "https://" is skipped, and evaluation continues to the right of the or.

Bottom-line for what the code does: it checks whether port == "443", and if it is, then "https://" is returned, otherwise "http://" is returned. Neither True nor False are possibly return values. The most accurate equivalent is:

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

In modern Python, you would write it like this:

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

One last assumption is that port is a string. A more robust version would support integer input, e.g., return "https://" if str(port) == "443" else "http://".

聊慰 2024-09-03 17:45:25

这是一个丑陋的黑客行为,不推荐。它之所以有效,是因为 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://"

This is an ugly hack that is not recommended. It works because of the short-circuiting behaviour of and and or and 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.

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

>>> 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://"
贪了杯 2024-09-03 17:45:25

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

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.

十六岁半 2024-09-03 17:45:25

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

a 和 b -->

if a:
  return b
else:
  return a

a或b-->

if a:
  return a
else:
  return b

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

a and b -->

if a:
  return b
else:
  return a

a or b -->

if a:
  return a
else:
  return b
月朦胧 2024-09-03 17:45:25

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

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

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

总而言之

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

请注意,此规则也适用于链接的全“and”或全“or”语句

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)**

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

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