是的,它是在 2.5 版中添加的 。表达式语法为:
a if condition else b
首先对condition
求值,然后根据condition
的布尔值对a
或b
的任意a
求值并返回。如果condition
评估为True
,那么a
评估和返回,但b
被忽略,否则当b
评估和返回,但a
被忽略。
这使得短路,因为当condition
是真实的,只有a
评价和b
是不是在所有的评估,但是,当condition
是假的只有b
进行评估, a
是不是在所有评估。
例如:
>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'
请注意,条件是表达式 ,而不是语句 。这意味着您不能在条件表达式中使用赋值语句或pass
或其他语句 :
>>> pass if False else x = 3
File "<stdin>", line 1
pass if False else x = 3
^
SyntaxError: invalid syntax
但是,您可以使用条件表达式来分配变量,如下所示:
x = a if True else b
将条件表达式视为在两个值之间切换。当您处于 “一个价值或另一个价值” 的情况下,它非常有用,但除此之外别无所求。
如果需要使用语句,则必须使用常规的if
语句而不是条件表达式 。
请记住,由于某些原因,某些 Pythonista 对此并不满意:
condition ? a : b
的顺序不同condition ? a : b
来自许多其他语言(例如 C,C ++,Go,Perl,Ruby,Java,Javascript 等)的三元运算符,当人们不熟悉 Python 的 “令人惊讶” 行为时可能会导致错误(它们可能会逆转)参数顺序)。 if
' 可能确实有用,并且可以使脚本更简洁,但确实会使代码复杂化) 如果您在记住顺序时遇到麻烦,请记住当大声朗读时,您(几乎)说出了您的意思。例如, x = 4 if b > 8 else 9
,则x = 4 if b > 8 else 9
大声读取x = 4 if b > 8 else 9
因为x will be 4 if b is greater than 8 otherwise 9
。
官方文件:
对于 2.5 之前的版本,有个窍门:
[expression] and [on_true] or [on_false]
当on_true
具有错误的布尔值时,它可能会给出错误的结果。 1 个
尽管这样做确实具有从左到右评估表达式的好处,但在我看来这很清楚。
<i><expression 1=""></expression></i> <b>if</b> <i><condition></condition></i> <b>else</b> <i><expression 2=""></expression></i>
a = 1
b = 2
1 if a > b else -1
# Output is -1
1 if a > b else -1 if a < b else 0
# Output is -1
作为Python 增强建议 308 的一部分,2006 年添加了 Python 中条件表达式的运算符。它的形式不同于常见的?:
运算符,它的形式是:
<expression1> if <condition> else <expression2>
等效于:
if <condition>: <expression1> else: <expression2>
这是一个例子:
result = x if a > b else y
可以使用的另一种语法(与 2.5 之前的版本兼容):
result = (lambda:y, lambda:x)[a > b]()
懒惰求操作数的地方。
另一种方法是通过索引元组(与大多数其他语言的条件运算符不一致):
result = (y, x)[a > b]
或明确构造的字典:
result = {True: x, False: y}[a > b]
另一种(可靠性较低)但更简单的方法是使用and
和or
运算符:
result = (a > b) and x or y
但是,如果x
为False
这将不起作用。
可能的解决方法是按如下所示制作x
和y
列表或元组:
result = ((a > b) and [x] or [y])[0]
要么:
result = ((a > b) and (x,) or (y,))[0]
如果您使用的是字典,则可以使用get(key, default)
来代替使用三元条件,例如:
shell = os.environ.get('SHELL', "/bin/sh")
资料来源: ?:维基百科中的 Python
不幸的是,
(falseValue, trueValue)[test]
解决方案没有短路行为;因此,无论条件如何,都会对falseValue
和trueValue
进行评估。这可能是次优的,甚至是错误的(即trueValue
和falseValue
都可能是方法,并且有副作用)。
一种解决方案是
(lambda: falseValue, lambda: trueValue)[test]()
(执行会延迟到知道获胜者为止;),但是会在可调用对象和不可调用对象之间引入不一致。此外,使用属性时无法解决问题。
故事就这样 - 在提到的 3 种解决方案之间进行选择是要在具有短路功能,至少使用Зython2.5(恕我直言不再是问题)和不易于 “ trueValue
-to-false” 之间进行trueValue
错误。
在这里,我只是试图说明几种编程语言之间在ternary operator
一些重要区别。
Javascript 中的三元运算符
var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0
Ruby 中的三元运算符
a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0
Scala 中的三元运算符
val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0
R 编程中的三元运算符
a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0
Python 中的三元运算符
a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
对于 Python 2.5 及更高版本,有一种特定的语法:
[on_true] if [cond] else [on_false]
在较旧的 Python 中,未实现三元运算符,但可以对其进行仿真。
cond and on_true or on_false
不过,有一个潜在的问题,如果cond
计算结果为True
,并on_true
评估为False
则on_false
返回,而不是on_true
。如果您想要这种行为,该方法可以,否则请使用以下方法:
{True: on_true, False: on_false}[cond is True] # is True, not == True
可以用以下方法包装:
def q(cond, on_true, on_false)
return {True: on_true, False: on_false}[cond is True]
并以这种方式使用:
q(cond, on_true, on_false)
它与所有 Python 版本兼容。
您可能经常会发现
cond and on_true or on_false
但这会在 on_true == 0 时导致问题
>>> x = 0
>>> print x == 0 and 0 or 1
1
>>> x = 1
>>> print x == 0 and 0 or 1
1
您期望普通三元运算符得到的结果
>>> x = 0
>>> print 0 if x == 0 else 1
0
>>> x = 1
>>> print 0 if x == 0 else 1
1