热门标签:
Q:

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

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

原网址
A:

是的,它是在2.5版本中添加的。 表达式语法为:

a if condition else b

首先计算condition,然后根据conditionBoolean值计算并返回conditioncondition中的一个。 如果condition求值为True,则condition被求值并返回但condition被忽略,否则当condition被求值并返回但condition被忽略时。

这允许短路,因为当condition为真时,只评估condition,而condition根本不评估,但是当condition为假时,只评估condition,而condition根本不评估。

例如:

>>> '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语句而不是条件表达式


请记住,由于几个原因,一些Pythonistas不赞成它:

  • 参数的顺序与经典的condition ? a : b来自许多其他语言的三元运算符(例如CC++GoPerlRubyJavaJavaScript等。),当不熟悉Python的"令人惊讶"行为的人使用它时(他们可能会颠倒参数顺序),这可能会导致错误。
  • 有些人发现它"笨拙",因为它违背了正常的思想流动(首先考虑条件,然后考虑效果)。
  • 文体原因。 (虽然'inlineif'可以是真正的有用,并使您的脚本更简洁,但它确实会使您的代码复杂化)

如果你在记住顺序时遇到困难,那么请记住,当大声朗读时,你(几乎)说出你的意思。 例如,x = 4 if b > 8 else 9被朗读为x will be 4 if b is greater than 8 otherwise 9

正式文件:

所有回答

共 29 条

author avatar

你可以索引成一个元组:

(falseValue, trueValue)[test]

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

可能更安全
(falseValue, trueValue)[test == True]

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

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

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

[expression] and [on_true] or [on_false]

on_true有一个错误的布尔值时,它可能会给出错误的结果。1

虽然它确实具有从左到右评估表达式的好处,但在我看来,这更清晰。

<子>1。 是否有相当于C的"?:"三元运算符?

author avatar

<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
author avatar

来自文档:

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

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

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

自2.5版本以来的新功能。

author avatar

作为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]

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

result = (a > b) and x or y

但是,如果 xFalse,则这不起作用。

一个可能的解决方法是制作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")

来源:?:在Python在维基百科

author avatar

不幸的是,

(falseValue, trueValue)[test]

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

解决这个问题的一个办法是

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

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

故事就是这样 - 在三个提到的解决方案之间进行选择是在具有短路功能,至少使用Python 2.5(恕我直言,不再是问题)和不容易出现"trueValue评估到错误"之间的权衡。

author avatar

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

在这里,我只是试图展示几种编程语言之间三元运算符的一些重要差异。

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
author avatar

对于Python2.5和更新版本,有一个特定的语法:

[on_true] if [cond] else [on_false]

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

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

author avatar

你可能经常会发现

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
author avatar

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

其引发aSyntaxError: invalid syntax。 所以上面要么是一个不完整的逻辑片段(也许用户期望在false条件下没有操作),要么可能打算使用expression2作为过滤器-注意以下是合法的Python:

[expression1 for element in iterable if expression2]

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

更窄的情况的替代语法:

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

expression1 if expression1 else expression2

expression1将不得不使用上述用法进行两次评估。 如果它只是一个局部变量,它可以限制冗余。 然而,在这个用例中,一个常见的、高性能的Pythonic习语是使用or的短切行为:

expression1 or expression2

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

author avatar

正如已经回答的那样,是的,Python中有一个三元运算符:

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

在许多情况下<expression 1>也用作布尔值<condition>。 然后可以使用短路评估

a = 0
b = 1

# Instead of this:
x = a if a else b
# Evaluates as 'a if bool(a) else b'

# You could use short-circuit evaluation:
x = a or b

短路评估的一大优点是链接两个以上表达式的可能性:

x = a or b or c or d or e

当使用函数时,它在细节上更加不同:

# Evaluating functions:
def foo(x):
    print('foo executed')
    return x


def bar(y):
    print('bar executed')
    return y


def blubb(z):
    print('blubb executed')
    return z


# Ternary Operator expression 1 equals to False
print(foo(0) if foo(0) else bar(1))
''' foo and bar are executed once
foo executed
bar executed
1
'''

# Ternary Operator expression 1 equals to True
print(foo(2) if foo(2) else bar(3))
''' foo is executed twice!
foo executed
foo executed
2
'''

# Short-circuit evaluation second equals to True
print(foo(0) or bar(1) or blubb(2))
''' blubb is not executed
foo executed
bar executed
1
'''

# Short-circuit evaluation third equals to True
print(foo(0) or bar(0) or blubb(2))
'''
foo executed
bar executed
blubb executed
2
'''

# Short-circuit evaluation all equal to False
print(foo(0) or bar(0) or blubb(0))
''' Result is 0 (from blubb(0)) because no value equals to True
foo executed
bar executed
blubb executed
0
'''

PS:当然,短路评估不是三元运算符,但通常在短路足够的情况下使用三元运算符。 它具有更好的可读性,可以链接。

author avatar

Python的条件表达式的替代方案之一

"yes" if boolean else "no"

以下是:

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

它有以下漂亮的扩展:

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

最短的选择仍然存在:

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

但除了

yes() if boolean else no()

如果要避免yes()no()的求值,因为在

(no(), yes())[boolean]  # bad

no()yes()都被评估。

author avatar

模拟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'
author avatar
a if condition else b

只要记住这个金字塔,如果你有记忆困难:

     condition
  if           else
a                   b 
author avatar

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

语法:

[on_true]如果[表达式]其他[on_false]

1-使用三元运算符的简单方法:

# 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-使用元组、字典和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])
# lambda 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-三元运算符可以写成嵌套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
author avatar

你可以做到这一点:

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

例子::

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

这将打印"奇数",如果数字是奇数或"偶数",如果数字是偶数。


结果:如果条件为true,则执行exp_1,否则执行exp_2。

注意:0,None,False,emptylist和emptyString评估为False。

并且除0以外的任何数据都计算为True。

以下是它的工作原理:

如果条件[condition]变为"True",则将计算expression_1,但不计算expression_2。

如果我们"和"0(零)的东西,结果将永远是假的。 所以在下面的声明中,

0 and exp

表达式exp根本不会被计算,因为带有0的"and"将始终计算为零,并且不需要计算表达式。 这就是编译器本身的工作方式,在所有语言中。

1 or exp

表达式exp根本不会被计算,因为带有1的"or"将始终为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,但是在使用了"或"之后,它将在"或"之后计算表达式exp2。


注意:-这种使用"或"和"和"的分支只能在expression_1不具有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];
author avatar

Vinko Vrsalovic的答案足够好。 只有一件事:

请注意,条件是表达式,而不是语句。 这意味着您不能在条件表达式

中使用赋值语句或pass或其他语句

Python3.8中的海象运算符

在Python3.8中引入walrus运算符之后,发生了一些变化。

(a := 3) if True else (b := 5)

给出a = 3b is not defined

(a := 3) if False else (b := 5)

给出a is not definedb = 5,和

c = (a := 3) if False else (b := 5)

给出c = 5a is not definedb = 5

即使这可能是丑陋的,赋值可以在Python3.8之后在条件表达式内部完成。 无论如何,在这种情况下,使用normalif语句仍然更好。

author avatar

更多的是一个提示而不是一个答案(我不需要重复明显的第一百次),但我有时会在这样的构造中使用它作为单行快捷方式:

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

,成为:

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

一些(很多:)可能会皱眉认为它是非节奏的(甚至Ruby-ish:),但我个人觉得它更自然-即,你如何表达它通常,加上在大块代码中更具视觉吸引力。

author avatar

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

<condition> ? <expression1> : <expression2>

起初,Python的仁慈的终身独裁者(我的意思是Guido van Rossum,当然)拒绝了它(作为非Pythonic风格),因为对于不习惯C语言的人来说很难理解。 另外,冒号:在Python中已经有很多用途。 在PEP308被批准后,Python终于收到了自己的快捷方式条件表达式(我们现在使用的):

<expression1> if <condition> else <expression2>

因此,首先它评估条件。 如果它返回Trueexpression1将被评估以给出结果,否则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'
author avatar

是的,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")
author avatar

其他答案正确地谈论Python三元运算符。 我想补充提到一个经常使用三元运算符的场景,但有一个更好的习惯用法。 这是使用默认值的方案。

假设我们想使用option_value与默认值,如果它没有设置:

run_algorithm(option_value if option_value is not None else 10)

或者,如果option_value从未设置为假值(0""等。),简单地

run_algorithm(option_value if option_value else 10)

然而,在这种情况下,一个更好的解决方案是简单地写

run_algorithm(option_value or 10)
author avatar

Python有一个三元的赋值形式;然而,甚至可能有一个更短的形式,人们应该知道。

根据条件,需要将一个值或另一个值分配给变量是很常见的。

>>> li1 = None
>>> li2 = [1, 2, 3]
>>>
>>> if li1:
...     a = li1
... else:
...     a = li2
...
>>> a
[1, 2, 3]

^这是做这类作业的长格式。

下面是三元形式。 但这不是最简洁的方式-请参阅最后一个例子。

>>> a = li1 if li1 else li2
>>>
>>> a
[1, 2, 3]
>>>

使用Python,您可以简单地使用or进行替代分配。

>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>

上面的工作原理是因为li1None,解释器在逻辑表达式中将其视为False。 然后解释器继续前进并计算第二个表达式,该表达式不是None,也不是空列表-因此它被分配给a

这也适用于空列表。 例如,如果您想分配a任何列表都有项目。

>>> li1 = []
>>> li2 = [1, 2, 3]
>>>
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>

知道这一点,每当你遇到这样的任务时,你就可以简单地完成这些任务。 这也适用于字符串和其他可迭代对象。 您可以指定a任何不为空的字符串。

>>> s1 = ''
>>> s2 = 'hello world'
>>>
>>> a = s1 or s2
>>>
>>> a
'hello world'
>>>

我一直喜欢C三元语法,但Python更进一步!

我知道有些人可能会说这不是一个很好的风格选择,因为它依赖于并非所有开发人员都能立即看到的机制。 我个人不同意这种观点。 Python是一种语法丰富的语言,有许多惯用的技巧,这些技巧对涉猎者来说并不是很明显的。 但是,你学习和理解底层系统的机制越多,你就越欣赏它。

author avatar

毕达哥拉斯的做事方式:

"true" if var else "false"

但总是存在一种不同的方式来做三元条件:

"true" and var or "false"
author avatar

有多种方法。 最简单的方法是使用"print"方法内的条件。

您可以使用

print("Twenty" if number == 20 else "Not twenty")

这相当于:

if number == 20:
    print("Twenty")
else:
    print("Not twenty")

这样,也可以打印两个以上的语句。 例如:

if number == 20:
    print("Twenty")
elif number < 20:
    print("Lesser")
elif 30 > number > 20:
    print("Between")
else:
    print("Greater")

可以写成:

print("Twenty" if number == 20 else "Lesser" if number < 20 else "Between" if 30 > number > 20 else "Greater")
author avatar

if else-if版本可以写成:

sample_set="train" if "Train" in full_path else ("test" if "Test" in full_path else "validation")
author avatar

是的,它有,但它不同于类似c语法的编程语言(这是condition ? value_if_true : value_if_false

在Python中,它是这样的:value_if_true if condition else value_if_false

示例:even_or_odd = "even" if x % 2 == 0 else "odd"

author avatar

我发现默认的Python语法val = a if cond else b很麻烦,所以有时我会这样做:

iif = lambda (cond, a, b): a if cond else b
# So I can then use it like:
val = iif(cond, a, b)

当然,它具有总是评估双方(ab)的缺点,但语法对我来说更清晰。

author avatar

链接多个运算符的巧妙方法:

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

author avatar

如果定义了一个变量,并且你想检查它是否有一个值,你可以使用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

相似问题