Zu den Antworten von @Hugh Bothwell, @mortehu und @glglgl.
Einrichten des Datensatzes für die Prüfung
import random
dataset = [random.randint(0,15) if random.random() > .6 else None for i in range(1000)]
Definieren Sie Implementierungen
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 durchführen
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
Offensichtlich ist die not_none
Funktion beantwortet die Frage des Auftraggebers korrekt und behandelt das "Falsy"-Problem. Sie ist auch am schnellsten und am einfachsten zu lesen. Wenn die Logik an vielen Stellen angewendet werden soll, ist dies eindeutig der beste Weg.
Wenn Sie ein Problem haben, bei dem Sie den ersten Nicht-Null-Wert in einer Iterable finden wollen, dann ist @mortehus Antwort der richtige Weg. Aber es ist eine Lösung für ein anderes Problem als OP, obwohl es diesen Fall teilweise behandeln kann. Es kann nicht eine Iterable UND einen Standardwert annehmen. Das letzte Argument wäre der Standardwert, der zurückgegeben wird, aber dann würden Sie in diesem Fall auch keine Iterable übergeben, da es nicht explizit ist, dass das letzte Argument ein Standardwert ist.
Sie könnten dann unten etwas machen, aber ich würde trotzdem not_null
für den Anwendungsfall Einzelwert.
def coalesce(*args, **kwargs):
default = kwargs.get('default')
return next((a for a in arg if a is not None), default)