Zu den Antworten von @Hugh Bothwell, @mortehu und @glglgl.
Setup-Datensatz zum Testen
import random
dataset = [random.randint(0,15) if random.random() > .6 else None for i in range(1000)]
Implementierungen definieren
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)
Testfunktion machen
def test_func(dataset, func):
default = 1
for i in dataset:
func(i, default)
Ergebnisse auf Mac i7 @ 2.7Ghz mit 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
Klar die not_none
Funktion beantwortet die Frage des OP eindeutig richtig und behandelt das "Falsy" -Problem. Es ist auch am schnellsten und am einfachsten zu lesen. Wenn Sie die Logik an vielen Stellen anwenden, ist dies eindeutig der beste Weg.
Wenn Sie ein Problem haben, bei dem Sie den ersten Wert ungleich Null in einer Iterable finden möchten, ist die Antwort von @ mortehu der richtige Weg. Es ist jedoch eine Lösung für ein anderes Problem als OP, obwohl es diesen Fall teilweise behandeln kann. Es kann kein iterierbares UND ein Standardwert annehmen. Das letzte Argument wäre der zurückgegebene Standardwert, aber dann würden Sie in diesem Fall kein iterables übergeben, und es ist nicht explizit, dass das letzte Argument ein Standardwert ist.
Sie könnten dann unten tun, aber ich würde immer noch not_null
für den Einzelwert-Anwendungsfall verwenden.
def coalesce(*args, **kwargs):
default = kwargs.get('default')
return next((a for a in arg if a is not None), default)
??
Betreiber wird als PEP 505 vorgeschlagen .