Python Idiom zu ersten Element oder None zurückgeben?
Der pythonische Ansatz ist das, was die am meisten hochgestimmte Antwort gezeigt hat, und es war das erste, was mir in den Sinn kam, als ich die Frage las. Hier ist, wie es zu verwenden, zunächst wenn die möglicherweise leere Liste in eine Funktion übergeben wird:
def get_first(l):
return l[0] if l else None
Und wenn die Liste von einer get_list
función:
l = get_list()
return l[0] if l else None
Neu in Python 3.8, Zuweisungsausdrücke
Zuweisungsausdrücke verwenden den In-Place-Zuweisungsoperator (informell Walross-Operator genannt), :=
, neu in Python 3.8, erlaubt es uns, die Prüfung und Zuweisung an Ort und Stelle durchzuführen, was den Einzeiler ermöglicht:
return l[0] if (l := get_list()) else None
Als langjähriger Python-Benutzer fühlt sich dies an, als ob wir versuchen, zu viel auf einer Zeile zu tun - ich denke, es wäre besser, die vermutlich ebenso leistungsfähig zu tun:
if l := get_list():
return l[0]
return None
Unterstützt wird diese Formulierung durch Tim Peters Aufsatz im PEP, in dem diese Änderung der Sprache vorgeschlagen wird. Auf die erste Formulierung ist er nicht eingegangen, aber aufgrund der anderen Formulierungen, die ihm gefallen haben, glaube ich nicht, dass er etwas dagegen hätte.
Andere Möglichkeiten, die hier gezeigt werden, mit Erklärungen
for
Als ich anfing, über clevere Möglichkeiten nachzudenken, kam mir dies als Zweites in den Sinn:
for item in get_list():
return item
Dies setzt voraus, dass die Funktion hier endet und implizit zurückkehrt None
si get_list
gibt eine leere Liste zurück. Der folgende explizite Code ist genau gleichwertig:
for item in get_list():
return item
return None
if some_list
Es wurde auch folgendes vorgeschlagen (ich habe den falschen Variablennamen korrigiert), das ebenfalls die implizite None
. Dies wäre der obigen Lösung vorzuziehen, da sie die logische Prüfung anstelle einer Iteration verwendet, die möglicherweise nicht stattfindet. Dies sollte einfacher sein, sofort zu verstehen, was passiert. Aber wenn wir für die Lesbarkeit und Wartbarkeit schreiben, sollten wir auch die explizite return None
am Ende:
some_list = get_list()
if some_list:
return some_list[0]
slice or [None]
und wählen Sie den nullten Index
Dies ist auch die Antwort, die am häufigsten hochgestuft wurde:
return (get_list()[:1] or [None])[0]
Der Slice ist unnötig und erzeugt eine zusätzliche Ein-Element-Liste im Speicher. Das Folgende sollte leistungsfähiger sein. Zur Erläuterung, or
gibt das zweite Element zurück, wenn das erste Element False
in einem booleschen Kontext, wenn also get_list
eine leere Liste zurückgibt, gibt der in den Klammern enthaltene Ausdruck eine Liste mit dem Wert "None" zurück, auf die dann mit dem Befehl 0
Index:
return (get_list() or [None])[0]
Der nächste nutzt die Tatsache, dass und gibt das zweite Element, wenn das erste ist True
in einem booleschen Kontext, und da er zweimal auf my_list verweist, ist er nicht besser als der ternäre Ausdruck (und technisch gesehen kein Einzeiler):
my_list = get_list()
return (my_list and my_list[0]) or None
next
Dann haben wir die folgende clevere Verwendung des eingebauten next
y iter
return next(iter(get_list()), None)
Zur Erklärung, iter
gibt einen Iterator mit einer .next
Methode. ( .__next__
in Python 3). Dann wird das eingebaute next
Anrufe, die .next
Methode und gibt, wenn der Iterator erschöpft ist, den von uns angegebenen Standardwert zurück, None
.
redundanter ternärer Ausdruck ( a if b else c
) und zurückfahren
Vorgeschlagen wurde das Folgende, doch wäre die Umkehrung vorzuziehen, da Logik in der Regel besser im positiven als im negativen Sinne verstanden wird. Da get_list
zweimal aufgerufen wird, würde dies schlecht funktionieren, es sei denn, das Ergebnis wird auf irgendeine Art und Weise zwischengespeichert:
return None if not get_list() else get_list()[0]
Die bessere Umkehrung:
return get_list()[0] if get_list() else None
Noch besser ist es, eine lokale Variable zu verwenden, so dass get_list
wird nur einmal aufgerufen, und Sie haben die empfohlene Pythonic-Lösung, die zuerst besprochen wurde:
l = get_list()
return l[0] if l else None