Щодо відповідей @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.7Ghz за допомогою 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
функція відповідає на питання ОП правильно і вирішує проблему "хибної". Це також найшвидший і найпростіший для читання. Якщо застосовувати логіку в багатьох місцях, це, очевидно, найкращий шлях.
Якщо у вас є проблема, коли ви хочете знайти перше ненулеве значення в ітерабелі, то відповідь @ mortehu - це шлях. Але це рішення іншої проблеми, ніж ОП, хоча він може частково впоратися з цією справою. Він не може приймати ітерабельне І значення за замовчуванням. Останнім аргументом було б повернене значення за замовчуванням, але тоді ви не переходите в ітерабельний в такому випадку, а також не явно, що останній аргумент є значенням за замовчуванням.
Потім ви можете зробити це нижче, але я все одно використовую 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 .