更简单的方法来简单地修正返回值

时间:2014-09-02 20:47:33

标签: python idioms

对我来说,这段代码在Python中可能有更好的方法:

val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data)
if val is None:
    val = 0

有吗?

可能的用例:

total = 0
for lot_of_data in lots_of_data_list:
    val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data)
    if val is None:
        val = 0
    total += val

我想在这里使用sum(),但当然:

TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'

3 个答案:

答案 0 :(得分:3)

针对您的具体用例:

from functools import partial
from operator import is_not
from itertools import ifilter

# Create a callable that only needs bar
f = partial(some_heavy_foo, slow=True, side_effects=True)

# Ignore None values
is_not_none = partial(is_not, None)

# Some return values of f that aren't None
total = sum(ifilter(is_not_none, f(bar=x) for x in lot_of_data))

答案 1 :(得分:1)

这取决于你真正想要的东西。我已经看到来自javascript人群的人倾向于喜欢or

val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data) or 0

因为这是一个非常常见的JavaScript用法。当然,这会将所有虚假值转换为0。在这种情况下,这可能很好,因为通常你不应该编写代码,而你不确定你是否有整数或列表或其他东西......

就个人而言,我更赞成准确地说出你的意思(即用你原来的方式写出来),但这只是我的偏好。

您也可以将检查推迟到下一行:

val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data)
total += 0 if val is None else val

但是,我并不相信这样会好很多......

答案 2 :(得分:0)

这很简洁,但如果你不习惯功能风格,我不确定它会好多少。正如在另一个答案中那样,对于任何“虚假”值,这给你0,并且总结一切。

tot = sum(map(lambda x: x if x else 0,
    [some_heavy_foo(slow=True, side_effects=True, bar=data) for data in lots_of_data]))