在Python中使用三元条件的最佳方法< 2.5

时间:2012-04-15 00:50:15

标签: python python-2.5 ternary

我必须忍受Python版本< 2.5(细节为2.4.3)

似乎三元运算符是从2.5开始在Python中引入的。对于那些不熟悉的人,Python> = 2.5中的三元运算符如下所示:

def do_ternary(flag):
    return "foo" if flag else "bar"

我想知道一些在早期版本的Python中模拟这个的解决方案。我可以肯定的是,如果......其他,但我正在寻找更多的pythonic,我不会羞于投入一些生产级别的代码:)

感谢您的帮助!

4 个答案:

答案 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

这适用于andor在python中的工作方式如下:

x or y   ->    if x is false, then y, else x
x and y  ->    if x is false, then x, else y

Source

这意味着我们得到大致相同的结果 - 只要true_value评估为True - 因此,例如,以下工作:

flag and [] or "bar"

由于[]评估为False

我仍然认为这不如简单地使用if / else块那样可读,因为除非你熟悉它,否则不清楚。

所以我建议使用:

if test:
    return true_value
else:
    return false_value

(用任务代替返回或任何需要的东西)。

相关问题