在Python中执行三元条件语句的最佳方法<;2.5

在Python中执行三元条件语句的最佳方法<;2.5,python,python-2.5,ternary,Python,Python 2.5,Ternary,我不得不忍受Python版本=2.5中的三元运算符如下所示: def do_ternary(flag): return "foo" if flag else "bar" 我想知道一些在Python的早期版本中模拟这一点的解决方案。如果……我肯定能做到。。。除此之外,我正在寻找更具python风格的东西,我不会羞于在产品级代码中添加这些代码:) 谢谢你的帮助 实现这一点的经典“诀窍”是: test and true_value or false_value 这与python中的和和或类

我不得不忍受Python版本<2.5(具体是2.4.3)

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

def do_ternary(flag):
    return "foo" if flag else "bar"
我想知道一些在Python的早期版本中模拟这一点的解决方案。如果……我肯定能做到。。。除此之外,我正在寻找更具python风格的东西,我不会羞于在产品级代码中添加这些代码:)


谢谢你的帮助

实现这一点的经典“诀窍”是:

test and true_value or false_value
这与python中的
类似:

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

这意味着我们得到大致相同的结果-只要
true\u值
的计算结果为
true
-因此,例如,以下方法不起作用:

由于
[]
计算结果为
False

我仍然认为这比简单地使用if/else块可读性差,因为除非您熟悉它,否则不清楚

因此,我建议使用:

if test:
    return true_value
else:
    return false_value

(在需要时,用分配或其他方式代替返回)。

用于此操作的经典“诀窍”是:

test and true_value or false_value
这与python中的
类似:

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

这意味着我们得到大致相同的结果-只要
true\u值
的计算结果为
true
-因此,例如,以下方法不起作用:

由于
[]
计算结果为
False

我仍然认为这比简单地使用if/else块可读性差,因为除非您熟悉它,否则不清楚

因此,我建议使用:

if test:
    return true_value
else:
    return false_value

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

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

["bar", "foo"][bool(flag)]
将产生与您问题中的三元数相同的输出


编辑:Dougal指出,这可能与三元组稍有不同,因为真值和假值都会被计算,这可能会产生副作用。

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

["bar", "foo"][bool(flag)]
将产生与您问题中的三元数相同的输出

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

正确的方法是:

(condition and (yes_value,) or (no_value,))[0]
它既能短路,又能解决
yes\u值本身错误的问题。很明显,如果你有理由避免这种混乱,就这么做吧;在您的示例中,两个条件都是常量表达式,因此您可以执行以下操作:

{True: yes_value, False: no_value}[bool(condition)]
或者更简洁地说:

(no_value, yes_value)[condition]
如果您确实需要短循环,但您确信yes_值永远不会为假,则可以修剪元组:

 condition and yes_value or no_value
但这可能只有在
yes\u值实际上是一个常量时才有效。如果这些都不适合您的口味或需求,只需使用一个简单的ol
If:
语句和一个中间变量即可

if condition:
    result = yes_value
else:
    result = no_value
执行所有
if/else
操作的正确方法是:

(condition and (yes_value,) or (no_value,))[0]
它既能短路,又能解决
yes\u值本身错误的问题。很明显,如果你有理由避免这种混乱,就这么做吧;在您的示例中,两个条件都是常量表达式,因此您可以执行以下操作:

{True: yes_value, False: no_value}[bool(condition)]
或者更简洁地说:

(no_value, yes_value)[condition]
如果您确实需要短循环,但您确信yes_值永远不会为假,则可以修剪元组:

 condition and yes_value or no_value
但这可能只有在
yes\u值实际上是一个常量时才有效。如果这些都不适合您的口味或需求,只需使用一个简单的ol
If:
语句和一个中间变量即可

if condition:
    result = yes_value
else:
    result = no_value

事实上,我在网上找到了一个非常优雅的Python解决方案:

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
def_如果(测试):
返回lambda备选方案:\
lambda结果:\
[延迟(结果)、延迟(备选)][未测试]()
def延迟(f):
如果可调用(f):返回f
其他:返回lambda:f
>>>事实=λn:_如果(n>>事实(100)
93326215443944152681699238856266700490715968264381621468599296389521759932299160894414639761565182862536979208272372375825118521091686400000000000000000L

你觉得这个怎么样?在我看来,它看起来很干净,很容易阅读。

事实上,我在网上找到了一个非常优雅的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
def_如果(测试):
返回lambda备选方案:\
lambda结果:\
[延迟(结果)、延迟(备选)][未测试]()
def延迟(f):
如果可调用(f):返回f
其他:返回lambda:f
>>>事实=λn:_如果(n>>事实(100)
93326215443944152681699238856266700490715968264381621468599296389521759932299160894414639761565182862536979208272372375825118521091686400000000000000000L

你觉得这个怎么样?在我看来,它看起来很干净,也很容易阅读。

你反对if flag:return“foo”或者:return“bar”不够时髦吗?或者有什么具体原因吗?逻辑很好,但它不是三元运算符。这不是真正的“时髦”问题或者不是,更多的是关于代码分解和编写干净的代码。我真的不喜欢在我的代码中有完整的if…else语句树。当你想在测试为真时做一些事情,或者做其他事情时,
if…:…else:…
似乎