我必须忍受Python版本< 2.5(细节为2.4.3)
似乎三元运算符是从2.5开始在Python中引入的。对于那些不熟悉的人,Python> = 2.5中的三元运算符如下所示:
def do_ternary(flag):
return "foo" if flag else "bar"
我想知道一些在早期版本的Python中模拟这个的解决方案。我可以肯定的是,如果......其他,但我正在寻找更多的pythonic,我不会羞于投入一些生产级别的代码:)
感谢您的帮助!
答案 0 :(得分:7)
执行if/else
所做的所有事情的正确的方式:
(condition and (yes_value,) or (no_value,))[0]
同时进行短路并解决了yes_value
本身就是假的问题。显然,如果你有理由避免这种污垢,那就这么做吧;在您的示例中,两个条件都是常量表达式,因此您可以执行以下操作:
{True: yes_value, False: no_value}[bool(condition)]
或更简洁:
(no_value, yes_value)[condition]
如果你做需要短路,但你确信yes_value永远不会是假的,你可以删除元组:
condition and yes_value or no_value
但这可能仅在yes_value
实际上是常数时才有效。如果这些都不符合您的品味或需求,只需使用带有中间变量的普通if:
语句
if condition:
result = yes_value
else:
result = no_value
答案 1 :(得分:4)
一个常见的技巧是使用列表索引,因为当需要整数时,False
/ True
会变成0
/ 1
。如果测试可能是假y或y,而不是布尔值,那么首先确保测试是布尔值的良好做法:
["bar", "foo"][bool(flag)]
将产生与你问题中的三元相同的输出。
编辑:Dougal指出这可能与三元组的行为略有不同,因为将评估真值和假值,这可能会产生副作用。
答案 2 :(得分:4)
实际上我在网上看到了一个看起来非常优雅的pythonic解决方案:
def _if(test):
return lambda alternative: \
lambda result: \
[delay(result), delay(alternative)][not not test]()
def delay(f):
if callable(f): return f
else: return lambda: f
>>> fact = lambda n: _if (n <= 1) (1) (lambda: n * fact(n-1))
>>> fact(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L
您如何看待这一个?在我看来,它看起来很干净,易于阅读。
答案 3 :(得分:1)
用于执行此操作的经典“技巧”是:
test and true_value or false_value
这适用于and
和or
在python中的工作方式如下:
x or y -> if x is false, then y, else x
x and y -> if x is false, then x, else y
这意味着我们得到大致相同的结果 - 只要true_value
评估为True
- 因此,例如,以下不工作:
flag and [] or "bar"
由于[]
评估为False
。
我仍然认为这不如简单地使用if / else块那样可读,因为除非你熟悉它,否则不清楚。
所以我建议使用:
if test:
return true_value
else:
return false_value
(用任务代替返回或任何需要的东西)。