Python 有三元条件运算符吗?

Does Python have a ternary conditional operator?

提问人:Devoted 提问时间:12/27/2008 最后编辑:Mateen UlhaqDevoted 更新时间:6/6/2023 访问量:2842107

问:

想改进这篇文章吗?提供此问题的详细答案,包括引文和解释为什么您的答案是正确的。没有足够细节的答案可能会被编辑或删除。

Python 中有三元条件运算符吗?

python 运算符 conditional-operator

评论

207赞 Brent Bradburn 1/10/2013
在上面评论中引用的 Python 3.0 官方文档中,这被称为“conditional_expressions”,并且定义非常隐晦。该文档甚至不包括“三元”一词,因此除非您确切知道要查找什么,否则您很难通过 Google 找到它。版本 2 文档更有帮助,包括指向“PEP 308”的链接,其中包括许多与此问题相关的有趣历史背景。
48赞 user313114 12/16/2014
“三元”(有三个输入)是这种推动的结果属性,而不是概念的定义属性。例如:SQL具有类似的效果,但完全不是三元的。case [...] { when ... then ...} [ else ... ] end
20赞 user313114 12/16/2014
ISO/IEC 9899(C 编程语言标准)第 6.5.15 节也称其为“条件运算符”
18赞 HelloGoodbye 6/9/2016
维基百科在文章“?:”中对此进行了彻底的介绍。
20赞 Scott Martin 8/15/2018
在 nobar 发表评论后的几年里,条件表达式文档已更新为:条件表达式(有时称为“三元运算符”)......

答:

9054赞 Vinko Vrsalovic 12/27/2008 #1

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

a if condition else b

首先计算,然后根据布尔值 计算 或 之一并返回 。如果计算结果为 ,则被计算并返回但被忽略,或者 when 被计算并返回但被忽略。conditionabconditionconditionTrueabba

这允许短路,因为只有 when is true 被评估并且根本不被评估,而 when is false only 被评估并且根本不被评估。conditionabconditionba

例如:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

请注意,条件语句是一个表达式,而不是一个语句。这意味着您不能在条件表达式中使用诸如 之类的语句,或者将赋值与(或“增强”赋值,如 )一起使用:pass=+=

>>> pass if False else pass
  File "<stdin>", line 1
    pass if False else pass
         ^
SyntaxError: invalid syntax

>>> # Python parses this as `x = (1 if False else y) = 2`
>>> # The `(1 if False else x)` part is actually valid, but
>>> # it can't be on the left-hand side of `=`.
>>> x = 1 if False else y = 2
  File "<stdin>", line 1
SyntaxError: cannot assign to conditional expression

>>> # If we parenthesize it instead...
>>> (x = 1) if False else (y = 2)
  File "<stdin>", line 1
    (x = 1) if False else (y = 2)
       ^
SyntaxError: invalid syntax

(在 3.8 及更高版本中,“walrus”运算符允许将值作为表达式进行简单的赋值,然后与此语法兼容。但请不要这样写代码;它很快就会变得非常难以理解。:=

同样,由于它是一个表达式,因此该部分是必需的else

# Invalid syntax: we didn't specify what the value should be if the 
# condition isn't met. It doesn't matter if we can verify that
# ahead of time.
a if True

但是,您可以使用条件表达式来分配变量,如下所示:

x = a if True else b

或者,例如,返回一个值:

# Of course we should just use the standard library `max`;
# this is just for demonstration purposes.
def my_max(a, b):
    return a if a > b else b

将条件表达式视为在两个值之间切换。当我们处于“一个值或另一个值”的情况下时,我们可以使用它,无论是否满足条件,我们都会对结果做同样的事情。我们使用表达式来计算值,然后对它做一些事情。如果您需要根据条件执行不同的操作,请改用普通语句if


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

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

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

官方文档:

评论

357赞 yota 1/25/2016
对于编码人员来说,这个顺序可能看起来很奇怪,但对于数学家来说听起来很自然。在大多数情况下,你也可以像 A 一样理解它,除了 C 时,你应该改用 B......f(x) = |x| = x if x > 0 else -x
173赞 Kal Zekdor 3/6/2016
使用时要注意操作顺序。例如,行 .如果 和 ,您可能期望它产生 4,但实际上它会产生 1。 是正确的用法。z = 3 + x if x < y else yx=2y=1z = 3 + (x if x > y else y)
20赞 Kal Zekdor 4/15/2016
关键是,如果要在计算条件执行其他计算,例如向结果添加值,则需要将附加表达式添加到两边(),或者将条件(或z = 3 + x if x < y else 3 + yz = 3 + (x if x < y else y)z = (x if x < y else y) + 3)
7赞 Dimesio 8/11/2017
@MrGeek,我明白你的意思了,所以你基本上会嵌套操作:“foo”,如果布尔别处(“bar”,如果布尔别处“foobar”)'
11赞 Albert van der Horst 6/17/2018
程序员比数学家更需要精确正确的表述,因为在数学中总是诉诸于基本概念。一个令人信服的论点是 % 运算符,模仿“mod”在数学中的使用方式将是一场灾难。所以不,我不接受你的论点。这就像坚持英制单位一样。Groetjes Albert
206赞 Michael Burr 12/27/2008 #2

文档中

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

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

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

从2.5版开始新增功能.

434赞 James Brady 12/27/2008 #3

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

[expression] and [on_true] or [on_false]

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

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

1. 是否有 C 的 “?:” 三元运算符的等价物?

评论

77赞 ThomasH 10/21/2009
补救措施是使用(测试和 [true_value] 或 [false_value])[0],这样可以避免这个陷阱。
8赞 volcano 1/13/2014
三元运算符通常执行速度更快(有时提高 10-25%)。
9赞 OrangeTux 8/5/2014
@volcano 你有我的资源吗?
6赞 mbomb007 3/20/2018
@OrangeTux 这是反汇编的代码。使用ThomasH建议的方法会更慢。
997赞 Landon Kuhn 1/23/2009 #4

您可以索引到元组中:

(falseValue, trueValue)[test]

test需要返回 TrueFalse
始终将其实现为以下形式可能更安全:

(falseValue, trueValue)[test == True]

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

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

评论

724赞 SilverbackNet 2/4/2011
请注意,这个总是计算所有内容,而 if/else 构造只计算获胜表达式。
144赞 Dustin Getz 3/9/2012
(lambda: print("a"), lambda: print("b"))[test==true]()
20赞 martineau 6/1/2012
应该注意的是,s 中的内容可以是任意表达式。此外,为了安全起见,您可以通过编写 来明确测试真实性。该函数自 v2.2.1 以来一直存在。[][bool(<expression>)]bool()
13赞 JDM 3/2/2016
我做过一个类似的伎俩 - 只有一两次,但做到了 - 通过索引到字典中,以和作为键: 我不知道这是否效率较低,但它至少避免了整个“优雅”与“丑陋”的争论。毫无疑问,您正在处理布尔值而不是 int。TrueFalse{True:trueValue, False:falseValue}[test]
123赞 gorsky 12/6/2009 #5

不幸的是,

(falseValue, trueValue)[test]

解决方案没有短路行为;因此,无论条件如何,两者都会被评估。这可能是次优的,甚至是错误的(即两者兼而有之,可能是方法,有副作用)。falseValuetrueValuetrueValuefalseValue

对此的一种解决方案是

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

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

故事是这样的 - 在上述三种解决方案之间进行选择是在具有短路功能、至少使用 Python 2.5(恕我直言,不再是问题)和不容易出现“-evaluates-to-false”错误之间进行权衡。trueValue

评论

4赞 Perkins 10/12/2018
虽然 lambdas 技巧的元组有效,但它所需的时间大约是三元运算符的 3 倍。只有当它可以取代一长串 .if else if
0赞 Neuron 3/28/2023
与三元运算符相比,这是非常不可读的
355赞 Simon Klee 5/27/2010 #6

<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

评论

96赞 Roy Tinker 10/5/2010
这强调了三元运算符的主要意图:值选择。它还表明,可以将多个三元链接在一起,形成一个表达式。
7赞 Jon Coombs 12/2/2014
@Craig,我同意,但知道没有括号时会发生什么也很有帮助。在实际代码中,我也倾向于插入显式的 parens。
1赞 mins 10/26/2020
用:return 3 if t > 10 else t/2
85赞 Paolo 4/25/2012 #7

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

[on_true] if [cond] else [on_false]

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

cond and on_true or on_false

尽管存在一个潜在的问题,即如果返回 (evareed to and evaates to then) 而不是 .如果你想要这种行为,该方法是可以的,否则使用这个:condTrueon_trueFalseon_falseon_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 版本兼容。

评论

4赞 9/26/2012
行为不相同 - 返回 ,而返回 。在这些情况下,解决方法是替换为,尽管这不是一个完美的解决方案。q("blob", on_true, on_false)on_falseon_true if cond else on_falseon_truecondcond is not None
7赞 Jonas Kölker 11/12/2013
为什么不代替?前者检查 的真实性,后者检查指针与对象的相等性。正如@AndrewCecil所强调的那样,是真实的,但它.bool(cond)cond is TruecondTrue"blob"is not True
59赞 Benoit Bertholon 1/14/2013 #8

您可能经常会发现

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
32赞 Sasikiran Vaddi 11/20/2013 #9

模拟 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'

评论

1赞 Grijesh Chauhan 12/27/2013
为什么不干脆你为什么使用函数result = (y, x)[a < b]lambda
6赞 glglgl 2/13/2014
@GrijeshChauhan 因为在“编译”表达式上,例如涉及函数调用等,这将在两种情况下执行。这可能不是需要的。
2赞 Jocer 12/14/2020
对于这个问题来说,函数的使用是矫枉过正lambda
0赞 SnzFor16Min 1/19/2021
@GrijeshChauhan 简而言之,这实现了所谓的“短路评估”。一般来说,或者可以写成——但我怀疑它有更好的性能,因此它的必要性。P ? x : yx if P else y(lambda:y, lambda:x)[P]()
181赞 kenorb 5/5/2015 #10

2006 年,作为 Python 增强提案 308 的一部分,添加了 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

一种可能的解决方法是生成 and 列表或元组,如下所示: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

评论

2赞 Walter Tross 2/10/2019
result = {1: x, 0: y}[a > b]是另一种可能的变体 ( 并且实际上是带有 值和TrueFalse10)
0赞 kta 11/2/2023
根据规定,表达式先于条件。经过一番练习,我现在能记住了。
54赞 Russia Must Remove Putin 11/18/2015 #11

Python 有三元条件运算符吗?

是的。从语法文件

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

感兴趣的部分是:

or_test ['if' or_test 'else' test]

因此,三元条件运算的形式为:

expression1 if expression2 else expression3

expression3将被延迟计算(即,仅当在布尔上下文中为 false 时才计算)。由于递归定义,你可以无限期地链接它们(尽管它可能被认为是糟糕的风格)。expression2

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

使用注意事项:

请注意,每个后面都必须跟一个 .学习列表推导式和生成器表达式的人可能会发现这是一个很难学习的课程 - 以下方法不起作用,因为 Python 需要第三个表达式来表达:ifelse

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

这引发了一个 . 因此,以上要么是一段不完整的逻辑(也许用户期望在错误条件下出现空操作),要么是可能打算用作过滤器 - 请注意,以下内容是合法的 Python:SyntaxError: invalid syntaxexpression2

[expression1 for element in iterable if expression2]

expression2用作列表推导式的过滤器,而不是三元条件运算符。

更窄情况的替代语法:

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

expression1 if expression1 else expression2

expression1必须使用上述用法进行两次评估。如果它只是一个局部变量,它可以限制冗余。但是,对于此用例,一个常见且高性能的 Pythonic 习语是使用 的快捷方式行为:or

expression1 or expression2

这在语义上是等价的。请注意,一些风格指南可能会出于清晰起见而限制这种用法 - 它确实在很少的语法中包含了很多含义。

评论

1赞 JSDBroughton 2/18/2016
expression1 or expression2与 JavaScript 相似并具有相同的缺点/优点expression1 || expression2
1赞 Russia Must Remove Putin 5/27/2016
谢谢,@selurvedu - 在你弄清楚之前,这可能会令人困惑。我以艰难的方式学习,所以你的方式可能没有那么难。;)在生成器表达式或列表推导式的末尾使用 if without the else,将过滤可迭代对象。在前面,它是一个三元条件操作,需要 else。干杯!!
0赞 tchrist 1/26/2019
@AaronHall 尽管您对所有实例的元语法使用是一致的,但通过命名将条件测试表达式与两个结果表达式区分开来,可能更容易理解;例如,.这在嵌套(又名链接)时尤为明显。看看这样读起来有多好?expressionNresult1 if condition else result2result1 if condition1 else result2 if condition2 else result3
1赞 Russia Must Remove Putin 1/27/2019
@tchrist感谢您的评论 - 如果您查看修订历史记录,这篇文章目前有两个修订版本。我的大多数其他答案,尤其是排名靠前的答案,已经一次又一次地被重新审视。这个答案从来没有引起我的注意,因为社区维基状态没有给我任何内容的荣誉,所以我从来没有看到任何关于它的投票。由于我现在真的没有时间对此进行编辑,青蛙知道将来什么时候会再次引起我的注意。我可以看到你已经编辑了最好的答案,所以请随时从这篇文章中借用/引用我的材料(如果提议,请引用我!
27赞 Todor Minakov 5/11/2016 #12

与其说是答案,不如说是提示(我不需要第一百次重复显而易见的事情),但我有时会在此类结构中将其用作单行快捷方式:

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

成为:

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

一些(许多:)可能会认为它不是 pythonic(甚至是 Ruby 式:)),但我个人认为它更自然——即,你通常如何表达它,而且在大代码块中更具视觉吸引力。

评论

8赞 frederick99 8/20/2017
我更喜欢你的答案。:-)print( 'yes' if conditionX else 'nah' )
1赞 Todor Minakov 10/26/2017
也就是说,如果你愿意在这两种情况下 - 而且它看起来更像python,我不得不承认:)但是,如果表达式/函数不相同怎么办 - 比如 - 获得唯一的真实print()print('yes') if conditionX else Trueprint()conditionX
0赞 Thierry Lathuille 10/22/2018
为了补充 Frederick99 的评论,另一个要避免的原因是它在 Python2 中给出了一个 SyntaxError。print('yes') if conditionX else print('nah')
0赞 Todor Minakov 10/22/2018
它给出语法错误的唯一原因是因为在 Python 2 中 print 是一个语句 - ,而在 Python 3 中它是一个函数 - 。这可以通过将其用作语句来解决,或者更好的是 - 。print "yes"print("yes")from future import print_function
105赞 Arun V Jose 8/22/2016 #13

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

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

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

评论

12赞 fralau 1/11/2018
这听起来可能固执己见;但它本质上说的是,一个从未见过三元运算符的人可能会理解 Python 语法,而很少有人会理解更常用的语法,除非他们首先被告知它的含义。
2赞 Albert van der Horst 6/17/2018
Algol68:a=.if。。真。。然后。1 .else.0 .fi。这也可以表示为 a=(.true.|1|0) 像往常一样,Algol68 是对其后继者的改进。
0赞 Varun Garg 11/5/2020
像 Ruby 这样简单的东西在 Python 中就是 Pitaprint a || '<alt text>'print a if a is not None else 'alt text'
2赞 lenz 11/16/2020
@VarunGarg 但是你当然可以用 Python 说。print(a or 'alt text')
27赞 Natesh bhat 8/20/2017 #14

您可以这样做:

[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(零)来“和”某物,则结果将始终为 false。所以在下面的声明中,

0 and exp

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

1 or exp

表达式 exp 根本不会计算,因为带有 1 的“or”将始终为 1。因此,计算表达式 exp 不会费心,因为结果无论如何都是 1(编译器优化方法)。

但是在

True and exp1 or exp2

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

同样在

False and exp1 or exp2

表达式 exp1 不会被计算,因为 False 等同于写 0 并且用 0 做“and”本身就是 0,但是在 exp1 之后,由于使用了 “or”,它将在 “or” 之后计算表达式 exp2。


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

如果您仍然希望使其适用于所有情况,而不管 exp_1 和 exp_2 真值是什么,请执行以下操作:

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

评论

0赞 moi 10/20/2017
如果要在上下文中使用它并计算为 false,则 将是 ,而不是 。使用接受的答案。x = [condition] and ([expression_1] or 1) or [expression_2]expression_1x1expression_1
28赞 Ali Hallaji 4/4/2018 #15

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

语法:

[on_true] 如果 [表达式] else [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

评论

1赞 Perkins 10/12/2018
请注意,三元运算符比嵌套的 if 更小(在内存中)且速度更快。此外,您的嵌套实际上并不是三元运算符的重写,并且会为 a 和 b 的选择值生成不同的输出(特别是如果一个是实现奇怪方法的类型)。if-else__ne__
15赞 realmanusharma 10/22/2018 #16

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

评论

0赞 realmanusharma 10/22/2018
我添加了一个单行语句示例来检查哪个数字很大,以便进一步详细说明
1赞 Thierry Lathuille 10/22/2018
print真的不是一个好的选择,因为这会在 Python2 中产生 SyntaxError。
0赞 realmanusharma 10/22/2018
@Thierry Lathuille 这里我使用了 print() 函数而不是 print 语句,print 函数用于 Python 3,而 print 语句用于 Python 2
0赞 Thierry Lathuille 10/22/2018
这个问题已经在 SO 上问过了,只需使用 Python 2 尝试一下,您就会自己看到。'print('hello') 是 Python 2.7 中完全有效的语法,但它的解析方式使上面的代码抛出 SyntaxError。
30赞 shivtej 12/6/2018 #17
a if condition else b

如果你记不住,就记住这个金字塔:

     condition
  if           else
a                   b 
16赞 Andy Jazz 12/25/2018 #18

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

<condition> ? <expression1> : <expression2>

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

<expression1> if <condition> else <expression2>

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

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

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'
38赞 Walter Tross 2/10/2019 #19

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

"yes" if boolean else "no"

如下所示:

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

它有以下不错的扩展:

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

最短的替代方案仍然是

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

这之所以有效,是因为.issubclass(bool, int)

不过要小心:替代方案

yes() if boolean else no()

不是

(no(), yes())[boolean]  # bad: BOTH no() and yes() are called

(no, yes)[boolean]()

只要使用完全相同的参数调用,就可以正常工作。如果不是,就像在noyes

yes("ok") if boolean else no()  # (1)

或在

yes("ok") if boolean else no("sorry")  # (2)

那么类似的替代方案要么不存在(1),要么几乎不可行(2)。(在极少数情况下,根据上下文,类似

msg = ("sorry", "ok")[boolean]
(no, yes)[boolean](msg)

可能是有道理的。

感谢 Radek Rojík 的评论

1赞 Yaakov Bressler 5/12/2019 #20

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

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

34赞 Frank 10/16/2019 #21

如前所述,是的,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:当然,短路评估不是三元算子,但通常在短路足够的情况下使用三元算子。它具有更好的可读性,并且可以链接。

10赞 Todd 3/11/2020 #22

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

上述方法自 is 起,解释器在逻辑表达式中将其视为 False。然后解释器继续计算第二个表达式,它不是,也不是一个空列表 - 所以它被分配给 ali1NoneNone

这也适用于空列表。例如,如果要分配包含项目的任何列表。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 是一种语法丰富的语言,具有许多惯用技巧,这些技巧对于涉猎者来说并不明显。但是,你对底层系统的机制了解得越多,你就越欣赏它。

评论

0赞 Peter Mortensen 2/6/2022
在“简单的此类任务”附近似乎缺少一些东西。
0赞 Todd 2/7/2022
“简化”此类分配 =) @PeterMortensen
0赞 TimH 10/20/2022
很有意思!两个问题:1)显然,如果恰好有一个 和 是真的,那么将返回它的值。如果返回与 相同的值,则将始终如一地计算为一个或另一个(按位置进行)?2)你如何解释什么回报?我无法用我的测试用例来理解它。li1li2li1 or li2bool(li1) bool(li2)li1 or li2li1 and li2
1赞 Todd 10/31/2022
@TimH:1)作业的右手子表达式从左到右解释。如果第一个是真值,则该值将分配给 var。如果它不是真实的,则分配第二个。2) 使用 and 运算并不像这个答案所讨论的那样是某种三元运算。
0赞 Baruc Almaguer 3/27/2020 #23

我发现默认的 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),但语法对我来说更清楚。

评论

4赞 eatsfood 4/29/2020
这似乎是工作量的两倍,RAM使用量更多,并且比更简单的陈述更加模糊。val = a if cond else b
0赞 Rainer Koirikivi 1/11/2021
而且两者每次都在这里得到评估,不像aba if cond else b
0赞 kj-crypto 4/2/2022
根据 PEP8 的说法,将 lambda 分配给变量是一种代码异味。Lambda 应仅用作就地函数。
12赞 user118967 5/20/2020 #24

其他答案正确地谈到了 Python 三元运算符。我想通过提及经常使用三元运算符的场景来补充,但对于该场景,有一个更好的成语。这是使用默认值的方案。

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

run_algorithm(option_value if option_value is not None else 10)

或者,如果从未设置为虚假值(、等),则只需option_value0""

run_algorithm(option_value if option_value else 10)

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

run_algorithm(option_value or 10)

评论

5赞 ruancomelli 10/20/2020
一个有价值的补充,但我不同意:并不比.它确实更短,但对我来说看起来很奇怪,可能会导致错误。例如,如果会发生什么?第一个代码段将运行,因为不是 .但是,第二个和第三个代码段将运行,因为是虚假的。这两个代码段并不等效,因此一个并不比另一个更好。显性比隐性好。option_value or 10option_value if option_value is not None else 10option_value = 0run_algorithm(0)option_valueNonerun_algorithm(10)0
0赞 user118967 10/22/2020
@ruancomelli:说得好。我修改了答案以反映该更正。
4赞 user118967 10/22/2020
至于它看起来很奇怪,我想知道它对你来说是否看起来很奇怪,因为你注意到了不精确性(它并不真正等同)。对我来说,这听起来很自然,因为它让我想起了用英语说:“使用这个或那个(如果第一个选项不可用)”。但这当然是主观的。知道它对每个人来说看起来都不自然是很有用的。
2赞 ruancomelli 10/29/2020
好多了!感谢您对“或”成语的解释。这对我来说看起来很奇怪,因为我倾向于认为是一个将两个参数映射到布尔值的函数,所以我希望它返回 either 或(这发生在许多其他编程语言中)。但是“使用这个或那个”是一个很好的助记符,肯定会帮助我(希望其他人)记住这种模式。orTrueFalse
30赞 David Chung 12/23/2020 #25

Vinko Vrsalovic的回答已经足够好了。只有一件事:

请注意,条件语句是一个表达式,而不是一个语句。这意味着您不能在条件表达式中使用赋值语句或其他语句pass

Python 3.8 中的 Walrus 运算符

在 Python 3.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

即使这可能很丑陋,也可以在 Python 3.8 之后的条件表达式完成赋值。无论如何,在这种情况下,最好还是使用普通语句if

评论

0赞 Andrew Anderson 8/4/2021
在第一个例子中:实际上它是一个冗余的第一个海象运算符。这将执行:(a := 3) if True else (b := 5)a = 3 if True else (b := 5)
2赞 Ddavid 8/5/2021
@AndrewAnderson 不,这不是多余的。您应该比较第一个示例和第二个示例。你可以把它们组合起来,并考虑一下:,你总是得到一个或分配,而不是两个。但是,请考虑 ,当 、 时,你将得到 和 ,其中两者都被分配了。(a := 3) if x else (b := 5)aba = 3 if x else (b := 5)x == Falsea = 5b = 5
0赞 Andrew Anderson 8/6/2021
是的,这是正确的:)。我只考虑过这种情况,当然是有限的。x=True
0赞 Ddavid 8/7/2021
因为我们并没有真正写下这段代码,所以第一个例子的原因只是与其他例子进行比较。if True else
7赞 Franz Gastring 12/30/2021 #26

Pythonic 的做事方式:

"true" if var else "false"

但是,也总是存在一种不同的三元条件方法:

"true" and var or "false"
3赞 DevLoverUmar 2/1/2022 #27

if else-if 版本可以写成:

sample_set="train" if "Train" in full_path else ("test" if "Test" in full_path else "validation")
4赞 Aldrin Saurov Sarker 2/6/2022 #28

有多种方法。最简单的方法是在“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")
3赞 Heroes Of Balkan 2/17/2022 #29

是的,它有,但它不同于类似 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"

12赞 George Imerlishvili 4/11/2022 #30

Python 中三元运算符的语法为:

[on_true] if [expression] else [on_false]

使用该语法,以下是我们如何使用 Python 的三元运算符重写上面的代码:

game_type = 'home'
shirt = 'white' if game_type == 'home' else 'green'

它仍然很清楚,但要短得多。请注意,表达式可以是任何类型的表达式,包括函数调用,该表达式返回计算结果为 True 或 False 的值。

0赞 user5128720 2/13/2023 #31

我有来自设备的数据作为字符串,并将其保留为重建字符串。条件表达式需要受 () 的限制。这允许有多个条件在一行中构建字符串。如果不是,似乎“其他”之后的任何内容都将被考虑在内。

    d0 = "-679 58 1029"
    d1 = d0.split(" ")

    strg = (d1[0][:-2] if len(d1[0])>= 3 else "0") + " " +d1[0][-2:]+ " "+ (d1[1][:-2] if len(d1[1])>= 3 else "0") + " " + d1[1][-2:] + " " +d1[2]
    print(strg)
1赞 PhPires13 6/6/2023 #32

是的,Python 有一个三元条件运算符,也称为条件表达式或三元运算符。Python 中三元运算符的语法为:

value_if_true if condition else value_if_false

下面是一个示例来说明其用法:

x = 5
result = "Even" if (x % 2 == 0) else "Odd"
print(result)

在此示例中,条件 x % 2 == 0 检查 x 是否能被 2 整除。如果条件为 True,则将值“Even”分配给变量结果。否则,将分配值“Odd”。输出将是:

Odd

在处理中等复杂度的操作时,最好使用括号,以提高可读性:

"Even" if (x % 2 == 0) else "Odd"

而不是:

"Even" if x % 2 == 0 else "Odd"

三元运算符是一种在一行中编写简单条件表达式的简洁方法。在根据条件赋值或构造表达式时,它特别有用。但是,对于更复杂的条件或更长的表达式,如果可能,通常最好使用 if-else 语句以提高可读性。