In C # gibt es einen Null-Koaleszenz-Operator (geschrieben als ??
), der eine einfache (kurze) Nullprüfung während der Zuweisung ermöglicht:
string s = null;
var other = s ?? "some default value";
Gibt es ein Python-Äquivalent?
Ich weiß, dass ich tun kann:
s = None
other = s if s else "some default value"
Aber gibt es einen noch kürzeren Weg (wo ich nicht wiederholen muss s
)?
python
null-coalescing-operator
Klaus Byskov Pedersen
quelle
quelle
??
Betreiber wird als PEP 505 vorgeschlagen .Antworten:
Ok, es muss geklärt werden, wie der
or
Bediener arbeitet. Es ist ein boolescher Operator und funktioniert daher in einem booleschen Kontext. Wenn die Werte nicht boolesch sind, werden sie für den Operator in boolesche Werte konvertiert.Beachten Sie, dass der
or
Operator nicht nurTrue
oder zurückgibtFalse
. Stattdessen wird der erste Operand zurückgegeben, wenn der erste Operand als wahr ausgewertet wird, und der zweite Operand, wenn der erste Operand als falsch ausgewertet wird.In diesem Fall wird der Ausdruck
x or y
zurückgegeben,x
wenn erTrue
bei der Konvertierung in einen Booleschen Wert true ist oder als true ausgewertet wird. Andernfalls wird es zurückgegebeny
. In den meisten Fällen dient dies dem gleichen Zweck wie der Null-Koaleszenz-Operator von C♯. Beachten Sie jedoch Folgendes:Wenn Sie Ihre Variable verwenden
s
, um etwas zu speichern, das entweder auf die Instanz einer Klasse verweist oderNone
(solange Ihre Klasse keine Mitglieder definiert__nonzero__()
und__len__()
), ist es sicher, dieselbe Semantik wie der Null-Koaleszenz-Operator zu verwenden.In der Tat kann es sogar nützlich sein, diese Nebenwirkung von Python zu haben. Da Sie wissen, welche Werte als falsch ausgewertet werden, können Sie damit den Standardwert auslösen, ohne ihn
None
speziell zu verwenden (z. B. ein Fehlerobjekt).In einigen Sprachen wird dieses Verhalten als Elvis-Operator bezeichnet .
quelle
s
es ein gültiger Wert ist, aber nicht wahr? (Ich kenne Python nicht, daher bin ich mir nicht sicher, ob das Konzept der 'Wahrheit' gilt.)None
und leere Container (einschließlich Zeichenfolgen) werden zusätzlich zur Konstante als falsch betrachtetFalse
. Fast alles andere gilt als wahr. Ich würde sagen, dass die Hauptgefahr hier darin besteht, dass Sie einen wahren Wert ohne Zeichenfolge erhalten, aber das ist in einigen Programmen kein Problem.datetime.time(0)
war auch falsch!Streng,
Andernfalls
s = False
wird"default value"
, was möglicherweise nicht das ist, was beabsichtigt war.Wenn Sie dies verkürzen möchten, versuchen Sie:
quelle
Consider x()?.y()?.z()
Hier ist eine Funktion, die das erste Argument zurückgibt, das nicht ist
None
:reduce()
Möglicherweise werden alle Argumente unnötig durchlaufen, auch wenn das erste Argument nicht vorhandenNone
ist. Sie können also auch diese Version verwenden:quelle
def coalesce(*arg): return next((a for a in arg if a is not None), None)
macht dasselbe wie Ihr letztes Beispiel in einer Zeile.Consider x()?.y()?.z()
Mir ist klar, dass dies beantwortet wird, aber es gibt eine andere Option, wenn Sie mit Objekten arbeiten.
Wenn Sie ein Objekt haben, könnte dies sein:
Sie können verwenden:
Mögen:
Durch Hinzufügen
{}
als Standardwert wird, wenn "Name" fehlt, ein leeres Objekt zurückgegeben und an den nächsten get übergeben. Dies ähnelt der null-sicheren Navigation in C #obj?.name?.first
.quelle
.get
, dies funktioniert nur fürgetattr()
.get
on dict verwendet nicht den Standardparameter, wenn der Wert None ist, sondern den Standardparameter, wenn der Wert nicht vorhanden ist, da sich der Schlüssel nicht im dict befindet.{'a': None}.get('a', 'I do not want None')
wird Ihnen trotzdemNone
als Ergebnis geben.Zusätzlich zu Julianos Antwort zum Verhalten von "oder": Es ist "schnell".
Manchmal ist es also eine nützliche Abkürzung für Dinge wie
quelle
Zusätzlich zur Antwort von @Bothwells (die ich bevorzuge) für einzelne Werte können Sie den neuen Walross-Operator (seit Python3.8) verwenden, um die Zuordnung von Funktionsrückgabewerten auf Null zu überprüfen:
Daher muss die
test
Funktion nicht zweimal bewertet werden (wie ina = 2 if test() is None else test()
).quelle
Falls Sie mehr als eine Null-Koaleszenzoperation verschachteln müssen, z.
model?.data()?.first()
Dies ist kein leicht zu lösendes Problem
or
. Es kann auch nicht gelöst werden,.get()
was einen Wörterbuchtyp oder ähnliches erfordert (und sowieso nicht verschachtelt werden kann) odergetattr()
werden, wenn wenn eine Ausnahme ausgelöst wird, wenn NoneType das Attribut nicht hat.Der relevante Pip, der erwägt, der Sprache eine Null-Koaleszenz hinzuzufügen, ist PEP 505, und die für das Dokument relevante Diskussion befindet sich im Python-Ideen- Thread.
quelle
Zu den Antworten von @Hugh Bothwell, @mortehu und @glglgl.
Setup-Datensatz zum Testen
Implementierungen definieren
Testfunktion machen
Ergebnisse auf Mac i7 @ 2.7Ghz mit Python 2.7
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.quelle
Für diejenigen wie mich, die hier gestolpert sind und nach einer praktikablen Lösung für dieses Problem gesucht haben, wenn die Variable undefiniert sein könnte, ist die nächste, die ich bekommen habe:
Beachten Sie, dass beim Einchecken von Globals eine Zeichenfolge benötigt wird, danach jedoch die tatsächliche Variable beim Überprüfen auf Werte verwendet wird.
Weitere Informationen zur Existenz von Variablen: Wie überprüfe ich, ob eine Variable vorhanden ist?
quelle
(variablename or False) == True
ist das gleiche wievariablename == True
Wenn Sie den Namen im Wörterbuch nicht finden können, wird der Standardwert zurückgegeben. Wenn der Name vorhanden ist, wird ein vorhandener Wert mit 1 hinzugefügt.
hoffe das kann helfen
quelle
Die beiden folgenden Funktionen haben sich bei vielen variablen Testfällen als sehr nützlich erwiesen.
quelle