Относительно ответов @Hugh Bothwell, @mortehu и @ glglgl.
Настройка набора данных для тестирования
import random
dataset = [random.randint(0,15) if random.random() > .6 else None for i in range(1000)]
Определить реализации
def not_none(x, y=None):
if x is None:
return y
return x
def coalesce1(*arg):
return reduce(lambda x, y: x if x is not None else y, arg)
def coalesce2(*args):
return next((i for i in args if i is not None), None)
Сделать тестовую функцию
def test_func(dataset, func):
default = 1
for i in dataset:
func(i, default)
Результаты для Mac i7 @ 2,7 ГГц с использованием Python 2,7
>>> %timeit test_func(dataset, not_none)
1000 loops, best of 3: 224 µs per loop
>>> %timeit test_func(dataset, coalesce1)
1000 loops, best of 3: 471 µs per loop
>>> %timeit test_func(dataset, coalesce2)
1000 loops, best of 3: 782 µs per loop
Очевидно, что функция not_none
правильно отвечает на вопрос ОП и решает проблему «ложных». Это также самый быстрый и легкий для чтения. Если применять логику во многих местах, это, безусловно, лучший путь.
Если у вас есть проблема, когда вы хотите найти 1-е ненулевое значение в итерируемом, то ответ @ mortehu - это путь. Но это решение другой проблемы , чем OP, хотя это может частично решить этот случай. Он не может принимать итерируемое И значение по умолчанию. Последним аргументом будет возвращаемое значение по умолчанию, но тогда вы не передадите итерируемое в этом случае, так как не очевидно, что последний аргумент является значением по умолчанию.
Тогда вы могли бы сделать это ниже, но я бы все равно использовал not_null
для варианта использования с одним значением.
def coalesce(*args, **kwargs):
default = kwargs.get('default')
return next((a for a in arg if a is not None), default)