Python是否有三元条件运算符?


Answers

你可以索引到一个元组中:

(falseValue, trueValue)[test]

test需要返回TrueFalse
始终将其实施为:

(falseValue, trueValue)[test == True]

或者您可以使用内置的bool()来确保一个Boolean值:

(falseValue, trueValue)[bool(<expression>)]
Question

如果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



是。

>>> b = (True if 5 > 4 else False)
>>> print b
True



作为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和操作符:

result = (a > b) and x or y

然而,如果x将是False这将不起作用。

可能的解决方法是使xy列表或元组如下所示:

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

资料来源: ?:




比回答更多的提示(不需要为hundreth时间重复显而易见),但我有时会将它用作此类构造中的一个简化的快捷键:

if conditionX:
    print('yes')
else:
    print('nah')

,变成:

print('yes') if conditionX else print('nah')

有些(很多:)可能会将它视为unpythonic(即使是ruby-ish :),但我个人觉得它更自然 - 也就是说如何正常表达它,再加上大块代码在视觉上更吸引人。




对于Python 2.5及更新版本,有一个特定的语法:

[on_true] if [cond] else [on_false]

在较老的Pythons中,三元运算符没有实现,但可以模拟它。

cond and on_true or on_false

虽然,有一个潜在的问题,如果cond评估为True并且on_true评估为False则返回on_true而不是on_true 。 如果你想要这个行为,那么这个方法是OK的,否则使用这个:

{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版本兼容。




In [1]: a = 1 if False else 0

In [2]: a
Out[2]: 0

In [3]: b = 1 if True else 0

In [4]: b
Out[4]: 1



Python是否有三元条件运算符?

是。 从语法文件中

test: or_test ['if' or_test 'else' test] | lambdef

感兴趣的部分是:

or_test ['if' or_test 'else' test]

所以,三元条件操作的形式是:

expression1 if expression2 else expression3

expression3将被延迟评估(即,只有在布尔上下文中expression2为false时才评估)。 由于递归定义,你可以无限期地链接它们(虽然它可能被认为是不好的风格)。

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

使用说明:

请注意,每个if必须跟一个else 。 人们学习列表理解和生成器表达式可能会发现这是一个难学的教训 - 以下将无法正常工作,因为Python期望第三个表达式为else:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

这引发了一个SyntaxError: invalid syntax 。 因此,上面的内容或者是一段不完整的逻辑(可能用户期望在假状态下没有操作),或者可能意图将expression2用作过滤器 - 注意以下内容是合法的Python:

[expression1 for element in iterable if expression2]

expression2作为列表理解的过滤器, 并不是三元条件运算符。

更窄范围的替代语法:

您可能会发现写下以下内容会有点痛苦:

expression1 if expression1 else expression2

expression1将不得不使用上面的用法评估两次。 它可以限制冗余,如果它只是一个局部变量。 然而,这种用例的一个常见和高性能的Pythonic惯用法是使用or是捷径行为:

expression1 or expression2

这在语义上是等价的。 请注意,一些风格指南可能会以清晰为理由限制这种用法 - 它确实将很多含义包含在很少的语法中。




在其他答案中有一个三元选项,但是如果您正在检查布尔值或无值,您还可以使用“或”来模拟它:

>>> a = False
>>> b = 5
>>> a or b
5

>>> a = None
>>> a or b
5



expression1 if condition else expression2

>>> a = 1
>>> b = 2
>>> 1 if a > b else -1 
-1
>>> 1 if a > b else -1 if a < b else 0
-1



Links