Python 条件运算符解决方法如何工作?

发布于 2024-08-15 21:36:18 字数 340 浏览 13 评论 0原文

根据我所读到的内容,我发现内置的三元运算符不存在(我很乐意了解更多信息)。

我找到了以下代码作为替代:

def val():
    var = float(raw_input("Age:"))
    status = ("Working","Retired")[var>65]
    print "You should be:",status

我无法理解这段代码是如何工作的;谁能解释一下代码实际上是如何工作的?我也有兴趣知道为什么三元运算符不存在;有关此的任何参考或链接都非常有用。

我在 Windows Vista 上运行 Python 2.6.4。

From what I have read, I found that a built-in ternary operator does not exist (I will be happy to know more about it.).

I found the following code as a substitute:

def val():
    var = float(raw_input("Age:"))
    status = ("Working","Retired")[var>65]
    print "You should be:",status

I couldn't understand how this code works; can anyone explain me how actually the code is working? I am also interested to know why the ternary operator doesn't exist; any references or links about this will be ore useful.

I'm running Python 2.6.4 on Windows Vista.

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

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

发布评论

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

评论(12

┈┾☆殇 2024-08-22 21:36:19

Python 的构造有点像 C 等中的三元运算符。它的工作原理如下:

my_var = "Retired" if age > 65 else "Working"

并且相当于此 C 代码:

my_var = age > 65 ? "Retired" : "Working";

至于您发布的代码如何工作,让我们逐步完成它:

("Working","Retired")

创建一个 2 元组(一个不可变列表),其元素“Working”位于索引 0 处,并且“在索引 1 处退休”。

var>65

如果 var 大于 65,则返回 True,否则返回 False。当应用于索引时,它会转换为 1 (True) 或 0 (False)。因此,这个布尔值提供了在同一行上创建的元组的索引。

为什么 Python 一直没有三元运算符?简单的答案是,Python 的作者 Guido van Rossum 不喜欢/不想要它,显然认为这是一个不必要的构造,可能会导致代码混乱(以及任何在 Python 中见过大量嵌套三元运算符的人)。 C 可能会同意)。但对于 Python 2.5,他态度软化并添加了上面看到的语法。

Python has a construct that is sort of like the ternary operator in C, et al. It works something like this:

my_var = "Retired" if age > 65 else "Working"

and is equivalent to this C code:

my_var = age > 65 ? "Retired" : "Working";

As for how the code you posted works, let's step through it:

("Working","Retired")

creates a 2-tuple (an immutable list) with the element "Working" at index 0, and "Retired" at index 1.

var>65

returns True if var is greater than 65, False if not. When applied to an index, it is converted into 1 (True) or 0 (False). Thus, this boolean value provides an index into the tuple created on the same line.

Why hasn't Python always had a ternary operator? The simple answer is that Guido van Rossum, the author of Python, didn't like/didn't want it, apparently believing that it was an unnecessary construct that could lead to confusing code (and anyone who's seen massively-nested ternary operators in C can probably agree). But for Python 2.5, he relented and added the grammar seen above.

a√萤火虫的光℡ 2024-08-22 21:36:19

Python(2.5 及更高版本)确实有您要查找的语法:

x = foo if condition else bar

如果 condition 为 True,x 将设置为 foo ,否则它将被设置为 bar

示例:

>>> age = 68
>>> x = 'Retired' if age > 65 else 'Working'
>>> x
'Retired'
>>> age = 35
>>> y = 'Retired' if age > 65 else 'Working'
>>> y
'Working'

Python (2.5 and above) does indeed have a syntax for what you are looking for:

x = foo if condition else bar

If condition is True, x will be set to foo, otherwise it will be set to bar.

Examples:

>>> age = 68
>>> x = 'Retired' if age > 65 else 'Working'
>>> x
'Retired'
>>> age = 35
>>> y = 'Retired' if age > 65 else 'Working'
>>> y
'Working'
忆依然 2024-08-22 21:36:19

因为 True 转换为 1,False 转换为 0,所以 if var = 70

("Working","Retired")[var>65]

成为

("Working", "Retired")[1]

一个不错的小快捷方式...但我发现除了简单的条件之外,它可能会有点令人困惑,所以我会接受 TM 的建议

"Retired" if var > 65 else "Working"

because True casts to 1 and False casts to 0 so if var = 70

("Working","Retired")[var>65]

becomes

("Working", "Retired")[1]

a nice little shortcut ... but I find it can be a little confusing with anything but a simple condition, so I would go with TM's suggestion

"Retired" if var > 65 else "Working"
葵雨 2024-08-22 21:36:19

索引到列表

利用

[expression_when_false, expression_when_true][condition] # or
(expression_when_false, expression_when_true)[condition]

了 Python 中 True 等于(但不是!)1 和 False 等于(但不是!)0 的优势。上面的表达式构造了一个包含两个元素的列表,并使用条件的结果在列表中索引并仅返回一个表达式。此方法的缺点是要对两个表达式进行求值。

and-or 快捷方式

自 Python 创建以来,出现了这种操作的一种形式:

condition and expression_when_true or expression_when_false

它采用快捷方式并仅计算一个表达式,但有一个容易出错的缺点:表达式_when_true 不得 计算结果为非真值,否则结果为 expression_when_falseandor 在 Python 中是“短路”,并且适用以下规则:

a and b #→ a if a is false, else b
a or b  #→ a if a is true, else b

如果 condition 为 false,则 expression_when_true< /em> 永远不会被求值,结果是 expression_when_false。 OTOH,如果条件为真,则结果是(表达式_when_true表达式_when_false)的结果;请参阅上表。

三元条件运算符

当然,从Python 2.5开始,有一个三元条件运算符:

expression_when_true if condition else expression_when_false

奇怪的(如果你习惯了类似C的三元条件运算符)操作数的顺序归因于 很多事情;一般意图是条件在大多数情况下都应该为真,以便最常见的输出首先出现并且最明显。

indexing into a list

The use of

[expression_when_false, expression_when_true][condition] # or
(expression_when_false, expression_when_true)[condition]

takes advantage of the fact that in Python True equals (but isn't!) 1 and False equals (but isn't!) 0. The expression above constructs a list of two elements, and uses the result of condition to index in the list and return only one expression. The drawback of this method is that both expressions are evaluated.

and-or shortcuts

Since the creation of Python, there was a form of this operation:

condition and expression_when_true or expression_when_false

This takes a shortcut and evaluates only one expression, but has a bug-prone drawback: the expression_when_true must not evaluate to a non-true value, otherwise the result is expression_when_false. and and or are "short-circuiting" in Python, and the following rules apply:

a and b #→ a if a is false, else b
a or b  #→ a if a is true, else b

If condition is false, then expression_when_true is never evaluated and the result is expression_when_false. OTOH, if condition is true, then the result is the result of (expression_when_true or expression_when_false); consult the table above.

ternary conditional operator

Of course, since Python 2.5, there is a ternary conditional operator:

expression_when_true if condition else expression_when_false

The strange (if you are accustomed to the C-like ternary conditional operator) order of the operands is attributed to many things; the general intention is that condition should be true most of the time, so that the most common output comes first and is most visible.

空城仅有旧梦在 2024-08-22 21:36:19

短路布尔表达式

还有一个用于短路逻辑运算的选项:

>>> (2+2 == 4) and "Yes" or "No"
'Yes'
>>> (2+2 == 5) and "Yes" or "No"
'No'

在您的示例中:

>>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
Age: 20
'Working'
>>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
Age: 70
'Retired'

迷人的 Python:Python 函数式编程,第 1 部分

Short-circuit boolean expressions

There is also an option to short-circuit logical operations:

>>> (2+2 == 4) and "Yes" or "No"
'Yes'
>>> (2+2 == 5) and "Yes" or "No"
'No'

In your example:

>>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
Age: 20
'Working'
>>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
Age: 70
'Retired'

Read more about this technique in Charming Python: Functional Programming in Python, Part 1.

始终不够 2024-08-22 21:36:19

在您发布的代码中,以下行模拟三元:

status = ("Working","Retired")[var>65]

这里元组 ("Working","Retired") 使用索引 [var>65] 访问,其计算结果为True (1) 或 False (0)。当使用索引 0 访问时,status 将为 'Working';如果索引是 1 那么它将是“退休”。这是一种相当晦涩的条件赋值方式,使用 py2.5 中引入的正常三元语法,如上所述。

in the code that you posted the following line is emulating ternary:

status = ("Working","Retired")[var>65]

here tuple ("Working","Retired") accessed with an index [var>65] which evaluates to either True (1) or False (0). When it's accessed with index 0, status will be 'Working'; if index is 1 then it'll be ``Retired'`. It's a fairly obscure way to do conditional assignment, use the normal ternary syntax that was introduced in py2.5 as was said.

蓝礼 2024-08-22 21:36:19

最初没有三元运算符,因为“显式优于隐式”,并且它被视为非Pythonic。我也不太喜欢python的三元运算,但它确实存在:

x = foo if condition else bar

如TM所示。

至于status = ("工作","退休")[var>65]
<代码>变量> 65 返回一个布尔值:True 或 False;然而,Python 对布尔类型的处理相当弱:在某些情况下,True1False0。您可以通过执行 >>> 来查看它真 == 1。

There was originally no ternary operator because "Explicit is better than implicit", and it was seen as unpythonic. I don't like python's ternary op too much, either, but it exists:

x = foo if condition else bar

as shown by TM.

As for status = ("Working","Retired")[var>65],
var > 65 returns a boolean value: either True or False; however, Python treats boolean types quite weakly: True is 1 and False is 0 in some contexts. You can check it out by doing >>> True == 1.

与之呼应 2024-08-22 21:36:19
status = ("Working","Retired")[var>65]

此行用作三元运算符,因为表达式 var>65 返回 1 或 0,具体取决于 var 是否大于 65。因此,如果 var>65,则该行变为:

status = ("Working","Retired")[1]

即序列 ("Working","Retired") 的第二个元素。这看起来很奇怪,但如果你这样写的话就不奇怪了:

status_sequence = ("Working","Retired")
status = status_sequence[1]

so status = "Retired"

同样,如果 var<=65 则变为

status = ("Working","Retired")[0]

status = "Working"

status = ("Working","Retired")[var>65]

This line works as a ternary operator because the expression var>65 returns 1 or 0, depending on whether var is bigger than 65 or not. So if var>65, then the line becomes this:

status = ("Working","Retired")[1]

that is, the second element of the sequence ("Working","Retired"). It looks odd but not if you write it like this instead:

status_sequence = ("Working","Retired")
status = status_sequence[1]

so status = "Retired".

Similarly, if var<=65 then it becomes

status = ("Working","Retired")[0]

and status = "Working".

蒲公英的约定 2024-08-22 21:36:19

该代码中只有“status =”行实现了类似三元运算符的功能。

status = ("Working","Retired")[var>65]

这将创建一个二元素元组,其中字符串“Working”位于索引 0 处,“Retired”位于索引 1 处。随后,它使用表达式 的结果索引到该元组以选择两个项目之一变量> 65。

如果 var 的值大于 65,则该表达式将返回 True(相当于 1,因此选择“退休”)。否则,它将返回 False(相当于 0,因此选择“工作”)。

然而,这种方法和三元运算符之间有一个关键的区别,尽管这在您的特定示例中并不重要。使用元组索引方法,两个值都会被计算,但只返回一个。使用三元运算符,实际上只计算两个值之一;这称为“短路”行为。在这样的情况下,这可能很重要:

status = funcA() if var > 65 else funcB()
status = (funcB(), funcA())[var > 65]

在第一种情况下,要么调用 funcA() ,要么调用 funcB() ,但绝不会同时调用两者。在后一种情况下,首先调用两者,并将结果存储在元组中——然后只选择一个并丢弃该元组。

这对于了解 funcA() 或 funcB() 是否具有“副作用”尤其重要,这意味着它们在执行时会更改其他数据。

Only the "status =" line of that code implements something like the ternary operator.

status = ("Working","Retired")[var>65]

This creates a two-element tuple, with strings 'Working' at index 0, and 'Retired' at index 1. Following this, it indexes into that tuple to pick one of the two items, using the results of the expression var > 65.

This expression will return True (equivalent to 1, thus picking 'Retired') if the value of var is greater than 65. Otherwise it will return False (equivalent to 0, thus picking 'Working').

There is a key difference between this approach and the ternary operator, however, although it doesn't matter in your particular example. With the tuple-indexing approach, both values are evaluated but only one is returned. With the ternary operator, only one of the two values is actually evaluated; this is referred to as "short-circuit" behaviour. It can matter in cases like this:

status = funcA() if var > 65 else funcB()
status = (funcB(), funcA())[var > 65]

In the first case, either funcA() is called or funcB() is called, but never both. In the latter case, both are called first, and the results are stored in the tuple -- then only one is picked and the tuple is discarded.

This is especially important to understand if either funcA() or funcB() have "side-effects", meaning they change other data as they execute.

瀞厅☆埖开 2024-08-22 21:36:19

在 Python 2.6 及更高版本中:

print "You should be {0}.".format("retired" if var>65 else "working")

在 Python 3.1 及更高版本中:

print ("You should be {}.".format("retired" if var>65 else "working"))

In Python 2.6 and up:

print "You should be {0}.".format("retired" if var>65 else "working")

In Python 3.1 and up:

print ("You should be {}.".format("retired" if var>65 else "working"))
看海 2024-08-22 21:36:19

这是 python 三元运算符的形式,

def val():
    var = float(raw_input("Age:"))
    status = "Retired" if var > 65 else "Working"
    print "You should be:",status

您显示的代码有点棘手:它创建一个两个元素元组,其元素位于位置 0 和 1。为了选择正确的元素,它使用返回布尔值但在 python 中返回布尔值的条件是整数,因此您可以将其用作特殊索引(它们可以是 0 或 1)。

this is the form with the python ternary operator

def val():
    var = float(raw_input("Age:"))
    status = "Retired" if var > 65 else "Working"
    print "You should be:",status

the code you showed is a bit tricky: it creates a two elements tuple whose elements are at position 0 and 1. to select the right element it uses a condition which return a boolean but booleans in python are integers so you can use it as special indexes (they can be either 0 or 1).

橘和柠 2024-08-22 21:36:19

尝试根据此处给出的答案给出完整的答案。

你发现的方式(请不要使用这个,因为它不太可读):

def val():
    var = float(raw_input("Age:"))
    status = ("Working","Retired")[var>65]
    print "You should be:",status

使用 python 2.5+ 语法:

def val():
    var = float(raw_input("Age:"))
    status = "Working" if var>65 else "Retired"
    print "You should be:",status

使用某些人仍然喜欢的另一种常见方法:

def val():
    var = float(raw_input("Age:"))
    status = var>65 and "Working" or "Retired"
    print "You should be:",status

我个人倾向于使用自操作数的顺序与 C 三元运算符相同。

编辑:
发现最后一种方法存在一些问题(谢谢 Roberto Bonvallet)。
来自维基百科:

如果 op1 可以,此代码将会中断
一个“假”值(None、False、0、an
空序列或集合,...)作为
表达式将返回 op2
(无论是真还是假)
而不是(虚假的)op1

,所以我的最终建议是使用 2.5+ 三元运算符,因为它简单、可读并且提供短路行为。

trying to give a complete answer based on the answers given here.

the way you found (please don't use this one because it is not very readable):

def val():
    var = float(raw_input("Age:"))
    status = ("Working","Retired")[var>65]
    print "You should be:",status

using the python 2.5+ syntax:

def val():
    var = float(raw_input("Age:"))
    status = "Working" if var>65 else "Retired"
    print "You should be:",status

using the other common method still preferred by some people:

def val():
    var = float(raw_input("Age:"))
    status = var>65 and "Working" or "Retired"
    print "You should be:",status

i personally tend to use the last since the order of the operands is the same as the C ternary operator.

EDIT:
found some problems with the last approach (thx Roberto Bonvallet).
from wikipedia:

this code would break if op1 could be
a "falsy" value (None, False, 0, an
empty sequence or collection, …) as
the expression would return op2
(whether it was truthy or falsy)
instead of the (falsy) op1

so my final suggestion would be to use the 2.5+ ternary operator since it is simple, readable and offers short-circuit behavior.

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