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

时间:2009-12-22 15:22:27

标签: python indexing boolean conditional-operator

根据我的阅读,我发现内置的三元运算符不存在(我很乐意了解它。)。

我发现以下代码作为替代:

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

我无法理解这段代码是如何工作的;任何人都可以解释我实际上代码是如何工作的?我也很想知道为什么三元运算符不存在;任何关于此的参考或链接都是有用的。

我在Windows Vista上运行Python 2.6.4。

12 个答案:

答案 0 :(得分:51)

Python有一个类似于C等人的三元运算符的结构。它的工作原理如下:

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

并且相当于这个C代码:

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

至于你发布的代码如何工作,让我们一步一步:

("Working","Retired")

创建一个2元组(一个不可变列表),其元素“Working”在索引0处,“Retired”在索引1处。

var>65
如果var大于65,则

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

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

答案 1 :(得分:9)

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'

答案 2 :(得分:8)

因为True转换为1而False转换为0所以如果var = 70

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

变为

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

一个不错的小捷径...但我觉得除了一个简单的条件之外,它可能有点令人困惑,所以我会选择TM的建议

"Retired" if var > 65 else "Working"

答案 3 :(得分:7)

索引到列表

使用

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

利用Python中的事实True等于(但不是!)1和False等于(但不是!)0。上面的表达式构造了两个元素的列表,并使用 condition 在列表中编制索引并只返回一个表达式。这种方法的缺点是两种表达式都要进行评估。

和/或快捷方式

自Python创建以来,有一种形式的操作:

condition and expression_when_true or expression_when_false

这需要一个快捷方式并且仅评估一个表达式,但是容易出现错误: expression_when_true 不能评估为非真值,否则结果是 expression_when_false andor在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 ,结果为 expression_when_false 。 OTOH,如果 condition 为真,那么结果是( expression_when_true expression_when_false )的结果;请参考上表。

三元条件运算符

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

expression_when_true if condition else expression_when_false

奇怪的(如果你习惯于类C语言的三元条件运算符)操作数的顺序归属于to many things;一般意图是 condition 在大多数情况下都应该是真的,因此最常见的输出首先出现并且最明显。

答案 4 :(得分:2)

短路布尔表达式

还有一个短路逻辑操作的选项:

>>> (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'

Charming Python: Functional Programming in Python, Part 1中了解有关此技术的更多信息。

答案 5 :(得分:0)

在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"))

答案 6 :(得分:0)

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

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

此处使用索引("Working","Retired")访问的元组[var>65],其评估为True1)或False0)。当使用索引0访问它时,status将为'Working';如果索引是1那么它将是“退休”。这是一种相当模糊的方式来进行条件赋值,使用py2.5中引入的常规三元语法,如上所述。

答案 7 :(得分:0)

这是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)。

答案 8 :(得分:0)

最初没有三元运算符,因为“明确比隐含更好”,它被视为unpythonic。我也不太喜欢python的三元运算,但它存在:

x = foo if condition else bar

如TM所示。

至于status = ("Working","Retired")[var>65]var > 65返回一个布尔值:True或False;但是,Python非常弱地处理布尔类型:在某些上下文中True1False0。您可以通过执行>>> True == 1来查看。

答案 9 :(得分:0)

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]

所以status = "Retired"

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

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

status = "Working"

答案 10 :(得分:0)

只有该代码的“status =”行实现类似于三元运算符的内容。

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

这会创建一个双元素元组,索引为0的字符串'Working'和索引1处的'Retired'。接下来,它使用表达式的结果索引到该元组中以选择这两个项中的一个var > 65

如果var的值大于65,该表达式将返回True(相当于1,因此选择'Retired')。否则它将返回False(相当于0,因此选择'Working')。

这种方法与三元运算符之间存在关键差异,但是,尽管在您的特定示例中无关紧要。使用元组索引方法,将评估这两个值,但只返回一个值。使用三元运算符,实际上只评估了两个值中的一个;这被称为“短路”行为。在这种情况下可能很重要:

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

在第一种情况下,要么调用funcA(),要么调用 funcB(),但不能同时调用它们。在后一种情况下,两者都被称为第一个,结果存储在元组中 - 然后只选择一个并丢弃元组。

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

答案 11 :(得分:0)

试图根据这里给出的答案给出一个完整的答案。

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

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三元运算符相同。

修改 发现最后一种方法存在一些问题(thx Roberto Bonvallet) 来自维基百科:

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

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