2

我必须忍受 Python 版本 < 2.5(具体来说是 2.4.3)

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

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

我想知道一些解决方案来在 Python 的早期版本中模拟这一点。我肯定可以用 if ... else 来做,但我正在寻找更 Pythonic 的东西,我不会因为放在一些生产级代码上而感到羞耻:)

谢谢您的帮助 !

4

4 回答 4

8

做所有事情的正确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:如果这些都不适合您的口味或需求,只需使用带有中间变量的纯 ol语句

if condition:
    result = yes_value
else:
    result = no_value
于 2012-04-15T01:08:01.533 回答
5

实际上,我在网上查找并发现了一个看起来非常优雅的 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

你觉得这个怎么样?在我看来,它看起来非常干净且易于阅读。

于 2012-04-15T01:17:45.593 回答
4

一个常见的技巧是使用列表索引,因为False/True变成0/1当需要整数时。如果测试可能是 false-y 或 true-y 而不是布尔值,最好先确保测试是布尔值:

["bar", "foo"][bool(flag)]

将产生与您问题中的三元相同的输出。

编辑:Dougal 指出这可能与三元的行为略有不同,因为将评估真值和假值,这可能会产生副作用。

于 2012-04-15T00:58:26.707 回答
1

用于执行此操作的经典“技巧”是:

test and true_value or false_value

这在 python 中的工作方式andor工作方式一样:

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

(用分配或任何需要的地方替换返回)。

于 2012-04-15T00:54:41.130 回答