Что касается ответов @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)
??
Оператор предлагается в качестве PEP 505 .