根据我的阅读,我发现内置的三元运算符不存在(我很乐意了解它。)。
我发现以下代码作为替代:
def val():
var = float(raw_input("Age:"))
status = ("Working","Retired")[var>65]
print "You should be:",status
我无法理解这段代码是如何工作的;任何人都可以解释我实际上代码是如何工作的?我也很想知道为什么三元运算符不存在;任何关于此的参考或链接都是有用的。
我在Windows Vista上运行Python 2.6.4。
答案 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 。 and
和or
在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]
,其评估为True
(1
)或False
(0
)。当使用索引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非常弱地处理布尔类型:在某些上下文中True
为1
而False
为0
。您可以通过执行>>> 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+三元运算符,因为它简单易读,并且提供短路行为。