如果Python没有三元条件运算符,是否可以使用其他语言结构模拟一个?
是的,它是在2.5版本中添加的.表达式语法是:
a if condition else b
首先condition
进行评估,然后根据布尔值对它们中的任何一个进行评估a
或b
评估并返回.如果求值为,则进行求值并返回但忽略,否则何时求值并返回但忽略.condition
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 "", line 1 pass if False else x = 3 ^ SyntaxError: invalid syntax
在这种情况下,您必须使用普通if
语句而不是条件表达式.
请记住,由于以下几个原因,一些Pythonist对此不满意:
参数的顺序condition ? a : b
与许多其他语言(例如C,C++,Go,Perl,Ruby,Java,Javascript等)的经典三元运算符的顺序不同,当人们不熟悉Python时,这可能会导致错误.令人惊讶的"行为使用它(它们可能会颠倒参数顺序).
有些人觉得它"笨拙",因为它与正常的思维流程相反(首先考虑条件然后再考虑影响).
文体的原因.
如果您在记住订单时遇到问题,请记住,当您大声朗读时,您(几乎)会说出您的意思.例如,if
大声朗读为x = 4 if b > 8 else 9
.
官方文件:
条件表达式
是否有相当于C的"?:"三元运算符?
您可以索引到元组:
(falseValue, trueValue)[test]
test
需要返回True或False.
总是将它实现为以下可能更安全:
(falseValue, trueValue)[test == True]
或者您可以使用内置bool()
来确保布尔值:
(falseValue, trueValue)[bool()]
对于2.5之前的版本,有诀窍:
[expression] and [on_true] or [on_false]
当on_true
具有false布尔值时,它可能会给出错误的结果.1
虽然它确实有从左到右评估表达式的好处,但在我看来更清楚.
1. 是否有相当于C的"?:"三元运算符?
expression1 if condition else expression2
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操作的最低优先级.
表达式
x if C else y
首先评估条件C(不是x); 如果C为真,则计算x并返回其值; 否则,评估y并返回其值.有关条件表达式的更多详细信息,请参阅PEP 308.
自2.5版以来的新版本.
作为Python Enhancement Proposal 308的一部分,2006年添加了Python中条件表达式的运算符.它的形式与普通?:
运营商不同,它是:
if else
这相当于:
if: else:
这是一个例子:
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
@up:
不幸的是,
(falseValue, trueValue)[test]
解决方案没有短路行为; 因此,无论条件如何,都会评估falseValue和trueValue.这可能是次优的甚至是错误的(即trueValue和falseValue都可能是方法并且有副作用).
对此的一个解决方案是
(lambda: falseValue, lambda: trueValue)[test]()
(执行延迟到获胜者已知;)),但它引入了可调用和不可调用对象之间的不一致.另外,它没有解决使用属性时的情况.
故事如此 - 在3个提到的解决方案之间进行选择是在具有短路功能,至少使用python 2.5(恕我直言不再是问题)之间进行权衡,而不是倾向于"trueValue-evaluates-to-false"错误.
在这里,我试着展示一些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]
在较旧的Pythons中,没有实现三元运算符,但可以模拟它.
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
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
这在语义上是等价的.请注意,某些样式指南可能会在明确的基础上限制此用法 - 它确实在很少的语法中包含了很多含义.
模拟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'
你可以这样做 :-
[condition] and [expression_1] or [expression_2] ;
例:-
print(number%2 and "odd" or "even")
如果数字是奇数,这将打印"奇数"或如果数字是偶数则打印"偶数".
注意: - 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将不会被计算,因为True and exp1
当exp1不为false时,它将为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] ;
三元条件运算符只允许在单行中测试条件替换多行if-else使代码紧凑.
[on_true] if [expression] else [on_false]
# 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
# 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
# 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
更多的提示而不是答案(不需要在hundreth时间重复显而易见的事情),但我有时会将其用作此类构造中的oneliner快捷方式:
if conditionX: print('yes') else: print('nah')
,成为:
print('yes') if conditionX else print('nah')
有些(很多:)可能会把它当作unpythonic(甚至是ruby-ish :),但我个人认为它更自然 - 即你如何正常表达它,以及在大块代码中更具视觉吸引力.
a if condition else b
如果您在记忆中遇到问题,请记住这个金字塔:
condition if else a b
许多派生自的编程语言C
通常具有以下三元条件运算符的语法:
? :
起初,
Python
乙 enevolent d ictator ˚F或大号 IFE(我的意思是吉多·范罗苏姆,当然)拒绝了(非Python化风格),因为它是挺难理解不习惯的人C
的语言。另外,冒号在中:
已经有很多用途Python
。在PEP 308批准后,Python
最终收到了自己的快捷方式条件表达式(我们现在使用的是):
if else
因此,首先它评估条件。如果返回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'
希望这可以帮助。