Python有三元条件运算符吗?

问题描述 投票:5180回答:21

如果Python没有三元条件运算符,是否可以使用其他语言结构模拟一个?

python operators ternary-operator conditional-operator python-2.5
21个回答
6297
投票

是的,它是版本2.5中的added。表达式语法是:

a if condition else b

首先对condition进行评估,然后根据ab值对Booleancondition中的一个进行评估和返回。如果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语句而不是条件表达式。


请记住,由于以下几个原因,一些Pythonist对此不满意:

  • 参数的顺序与许多其他语言(例如C,C ++,Go,Perl,Ruby,Java,Javascript等)的经典condition ? a : b三元运算符的顺序不同,当人们不熟悉Python时,这可能会导致错误“令人惊讶”的行为使用它(它们可能会颠倒参数顺序)。
  • 有些人觉得它“笨拙”,因为它与正常的思维流程相反(首先考虑条件然后再考虑影响)。
  • 文体的原因。 (虽然'inline if'非常有用,并且使您的脚本更简洁,但它确实使您的代码复杂化)

如果您在记住订单时遇到问题,请记住,当您大声朗读时,您(几乎)会说出您的意思。例如,x = 4 if b > 8 else 9被大声朗读为x will be 4 if b is greater than 8 otherwise 9

官方文件:


35
投票

你可能经常会发现

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

28
投票

Does Python have a ternary conditional operator?

是。来自grammar file

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

感兴趣的部分是:

or_test ['if' or_test 'else' test]

因此,三元条件操作的形式如下:

expression1 if expression2 else expression3

expression3将被懒惰地评估(即,仅当expression2在布尔上下文中为假时才进行评估)。而且由于递归定义,你可以无限地链接它们(虽然它可能被认为是糟糕的风格。)

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

A note on usage:

请注意,每个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用作列表推导的过滤器,并不是三元条件运算符。

Alternative syntax for a more narrow case:

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

expression1 if expression1 else expression2

expression1必须按上述用途进行两次评估。如果它只是一个局部变量,它可以限制冗余。然而,这个用例的常见和高性能的Pythonic习语是使用or的快捷行为:

expression1 or expression2

这在语义上是等价的。请注意,某些样式指南可能会在明确的基础上限制此用法 - 它确实在很少的语法中包含了很多含义。


17
投票

模拟python三元运算符。

例如

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

输出:

'b greater than a'

15
投票

你可以这样做 :-

[condition] and [expression_1] or [expression_2] ;

例:-

print(number%2 and "odd" or "even")

如果数字是奇数,这将打印“奇数”或如果数字是偶数则打印“偶数”。


The result :- If condition is true exp_1 is executed else exp_2 is executed.

注意: - 0,None,False,emptylist,emptyString计算结果为False。并且除0之外的任何数据都评估为True。

以下是它的工作原理:

如果条件[条件]变为“真”,那么将评估expression_1但不计算表达式_2。如果我们“和”带0(零)的东西,结果总是很明显。所以在下面的陈述中,

0 and exp

表达式exp将不会被评估,因为“和”0将始终求值为零,并且不需要计算表达式。这是编译器本身在所有语言中的工作方式。

1 or exp

表达式exp将不会被评估,因为“或”1总是为1.所以它不会费心去评估表达式exp,因为结果将是1。 (编译器优化方法)。

但是如果是的话

True and exp1 or exp2

第二个表达式exp2将不会被计算,因为当exp1不为false时,True and exp1将为True。

同样地

False and exp1 or exp2

表达式exp1将不会被计算,因为False相当于写0并且0表示“和”本身是0但是在使用“或”之后的exp1之后,它将在“或”之后计算表达式exp2。


注意: - 这种使用“或”和“和”的分支只能在expression_1的Truth值不为False(或0或None或emptylist []或emptystring''时使用。)因为expression_1变为如果为false,则将评估expression_2,因为exp_1和exp_2之间存在“或”。

如果您仍然想让它适用于所有情况,无论exp_1和exp_2的真值是什么,请执行以下操作: -

[condition] and ([expression_1] or 1) or [expression_2] ;


14
投票

三元条件运算符只允许在单行中测试条件替换多行if-else使代码紧凑。

Syntax :

[on_true] if [expression] else [on_false]

1- Simple Method to use ternary operator:

# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min)  # Output: 10

2- Direct Method of using tuples, Dictionary, and lambda:

# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lamda is more efficient than above two methods
# because in lambda  we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10

3- Ternary operator can be written as nested if-else:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
        if a > b else "b is greater than a")

以上方法可写为:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
    if a > b:
        print("a is greater than b")
    else:
        print("b is greater than a")
else:
    print("Both a and b are equal") 
# Output: b is greater than a

12
投票

更多的提示而不是答案(不需要在hundreth时间重复显而易见的事情),但我有时会将它用作此类构造中的oneliner快捷方式:

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

,成为:

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

有些(很多:)可能会把它当作unpythonic(甚至是ruby-ish :),但我个人认为它更自然 - 也就是说你如何正常表达它,加上在大块代码中更具视觉吸引力。


9
投票
a if condition else b

如果您在记忆中遇到问题,请记住这个金字塔:

     condition
  if           else
a                   b 

4
投票

是的,python有一个三元运算符,这里是语法和示例代码来演示相同的:)

#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false


a= input("Enter the First Number ")
b= input("Enter the Second Number ")

print("A is Bigger") if a>b else print("B is Bigger")

4
投票

C派生的许多编程语言通常具有以下三元条件运算符的语法:

<condition> ? <expression1> : <expression2>

起初,Python仁慈的生命独裁者(我的意思是Guido van Rossum,当然)拒绝它(作为非Pythonic风格),因为对于不习惯C语言的人来说很难理解。此外,结肠标志:已经在Python有很多用途。在PEP 308获得批准后,Python终于收到了自己的快捷条件表达式(我们现在使用的):

<expression1> if <condition> else <expression2>

所以,首先评估条件。如果它返回True,将评估expression1以给出结果,否则将评估expression2。由于懒惰评估机制 - 只会执行一个表达式。

以下是一些示例(条件将从左到右评估):

pressure = 10
print('High' if pressure < 20 else 'Critical')

# Result is 'High'

三元运算符可以串联链接:

pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')

# Result is 'Normal'

以下一个与前一个相同:

pressure = 5

if pressure < 20:
    if pressure < 10:
        print('Normal')
    else:
        print('High')
else:
    print('Critical')

# Result is 'Normal'

希望这可以帮助。


3
投票

Python的conditional expression的替代方案之一如下:

{True:"yes", False:"no"}[boolean]

它有以下很好的扩展:

{True:"yes", False:"no", None:"maybe"}[boolean_or_none]

最短的替代品仍然存在:

("no", "yes")[boolean]

但如果你想避免在下面对yes()no()进行评估,则别无选择:

yes() if [condition] else no()

696
投票

您可以索引到元组:

(falseValue, trueValue)[test]

test需要返回正确或错误。 总是将它实现为以下可能更安全:

(falseValue, trueValue)[test == True]

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

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

-1
投票

如果定义了变量,并且你想检查它是否有价值,你可以只需a or b

def test(myvar=None):
    # shorter than: print myvar if myvar else "no Input"
    print myvar or "no Input"

test()
test([])
test(False)
test('hello')
test(['Hello'])
test(True)

将输出

no Input
no Input
no Input
hello
['Hello']
True

-1
投票

链接多个运算符的简洁方法:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'

array = [(0,0),(0,1),(1,0),(1,1)]

for a in array:
  x, y = a[0], a[1]
  print(f(x,y))

# Output is:
#   equal,
#   less,
#   greater,
#   equal


293
投票

对于2.5之前的版本,有诀窍:

[expression] and [on_true] or [on_false]

on_true具有错误的布尔值时,它可能会给出错误的结果 虽然它确实有从左到右评估表达式的好处,但在我看来这更清晰。

1. Is there an equivalent of C’s ”?:” ternary operator?


206
投票

<expression 1> if <condition> else <expression 2>

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

126
投票

来自the documentation

条件表达式(有时称为“三元运算符”)具有所有Python操作的最低优先级。

表达式x if C else y首先评估条件C(不是x);如果C为真,则计算x并返回其值;否则,评估y并返回其值。

有关条件表达式的更多详细信息,请参阅PEP 308

自2.5版以来的新版本。


96
投票

作为Python Enhancement Proposal 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]()

操作数是lazily evaluated

另一种方法是索引一个元组(与大多数其他语言的条件运算符不一致):

result = (y, x)[a > b]

或明确构造的字典:

result = {True: x, False: y}[a > b]

另一个(不太可靠),但更简单的方法是使用andor运算符:

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

资料来源:?: in Python at Wikipedia


85
投票

不幸的是,

(falseValue, trueValue)[test]

解决方案没有短路行为;因此,无论条件如何,都要评估falseValuetrueValue。这可能是次优的甚至是错误的(即trueValuefalseValue都可能是方法并且具有副作用)。

对此的一个解决方案是

(lambda: falseValue, lambda: trueValue)[test]()

(执行延迟到获胜者已知;)),但它引入了可调用和不可调用对象之间的不一致。另外,它没有解决使用属性时的情况。

故事就是这样 - 在3个提到的解决方案之间进行选择是在具有短路功能,至少使用Зython2.5(恕我直言不再是问题)之间进行权衡,而不是倾向于“trueValue-evaluates-to-false”错误。


56
投票

三元运算符在不同的编程语言中

在这里,我只是尝试在几种编程语言之间展示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

55
投票

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

[on_true] if [cond] else [on_false]

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

cond and on_true or on_false

虽然,有一个潜在的问题,如果cond评估Trueon_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版本兼容。

© www.soinside.com 2019 - 2024. All rights reserved.