Более идиоматический способ сделать простую коррекцию возвращаемого значения

Этот код для меня выглядит так, как будто в 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 ответа

Решение

Для вашего конкретного случая использования:

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))

Это зависит от того, что вы действительно хотите. Я видел, что людям из толпы 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

но я не уверен, что это намного лучше...

Это лаконично, но если вы не привыкли к функциональному стилю, я не уверен, что он намного лучше. Как и в другом ответе, это дает вам 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]))
Другие вопросы по тегам