Ich habe eine Frage zu Redewendungen und Lesbarkeit, und es scheint einen Konflikt zwischen Python-Philosophien für diesen speziellen Fall zu geben:
Ich möchte Wörterbuch A aus Wörterbuch B erstellen. Wenn in B kein bestimmter Schlüssel vorhanden ist, tun Sie nichts und fahren Sie fort.
Welcher Weg ist besser?
try:
A["blah"] = B["blah"]
except KeyError:
pass
oder
if "blah" in B:
A["blah"] = B["blah"]
"Tu und bitte um Vergebung" vs. "Einfachheit und Aussagekraft".
Welches ist besser und warum?
python
idioms
readability
defaultdict
code-readability
LeeMobile
quelle
quelle
if "blah" in B.keys()
oder geschrieben seinif B.has_key("blah")
.A.update(B)
bei dir nichthas_key
wurde zugunsten vonin
und ÜberprüfungB.keys()
einer O (1) -Operation in eine O (n) -Operation veraltet ..has_key
ist veraltet undkeys
erstellt nicht benötigte Liste in py2k und ist in py3k redundantA = dict((k, v) for (k, v) in B if we_want_to_include(k))
.Antworten:
Ausnahmen sind keine Bedingungen.
Die bedingte Version ist klarer. Das ist natürlich: Dies ist eine unkomplizierte Flusskontrolle, für die Bedingungen ausgelegt sind, keine Ausnahmen.
Die Ausnahmeversion wird hauptsächlich als Optimierung verwendet, wenn diese Suchvorgänge in einer Schleife ausgeführt werden: Bei einigen Algorithmen können Tests aus inneren Schleifen entfernt werden. Diesen Vorteil hat es hier nicht. Es hat den kleinen Vorteil, dass es nicht
"blah"
zweimal gesagt werden muss, aber wenn Sie viele davon tun, sollten Sie wahrscheinlichmove_key
trotzdem eine Hilfsfunktion haben.Im Allgemeinen würde ich dringend empfehlen, standardmäßig bei der bedingten Version zu bleiben, es sei denn, Sie haben einen bestimmten Grund, dies nicht zu tun. Bedingungen sind der naheliegende Weg, um dies zu tun. Dies ist normalerweise eine starke Empfehlung, eine Lösung einer anderen vorzuziehen.
quelle
"blah"
häufiger schreiben müssen, was zu einer fehleranfälligeren Situation führt.Es gibt auch einen dritten Weg, der sowohl Ausnahmen als auch die doppelte Suche vermeidet. Dies kann wichtig sein, wenn die Suche teuer ist:
Für den Fall , erwarten Sie das Wörterbuch enthalten
None
Werte, können Sie einige exotischere Konstanten wie verwendenNotImplemented
,Ellipsis
oder einen neuen machen:Auf jeden Fall
update()
ist die Verwendung für mich die am besten lesbare Option:quelle
Soweit ich weiß, möchten Sie Diktat A mit Schlüssel-Wert-Paaren aus Diktat B aktualisieren
update
ist eine bessere Wahl.Beispiel:
quelle
A.update({k: v for k, v in B.iteritems() if k in specificset})
Direktes Zitat aus dem Python-Performance-Wiki:
Es scheint also, dass beide Optionen je nach Situation realisierbar sind. Weitere Informationen finden Sie unter folgendem Link: Try-Except-Performance
quelle
Ich denke, die allgemeine Regel hier ist
A["blah"]
normalerweise, wenn ja, versuchen Sie es - außer ist gut, wenn nicht, dann verwenden Sieif "blah" in b:
Ich denke, "versuchen" ist in der Zeit billig, aber "außer" ist teurer.
quelle
Ich denke, das zweite Beispiel ist das, wofür Sie sich entscheiden sollten, es sei denn, dieser Code macht Sinn:
Beachten Sie, dass der Code abgebrochen wird, sobald ein Schlüssel nicht vorhanden ist
B
. Wenn dieser Code sinnvoll ist, sollten Sie die Ausnahmemethode verwenden, andernfalls die Testmethode. Meiner Meinung nach ist es viel einfacher zu lesen als die Ausnahmemethode, da es kürzer ist und die Absicht klar zum Ausdruck bringt.Natürlich sind die Leute, die Ihnen sagen, dass Sie verwenden
update
sollen, korrekt. Wenn Sie eine Version von Python verwenden, die das Verständnis von Wörterbüchern unterstützt, würde ich diesen Code sehr bevorzugen:quelle
for key in ["foo", "bar", "baz"]: try: A[key] = B[key]
In anderen Sprachen gilt die Regel, Ausnahmen für außergewöhnliche Bedingungen zu reservieren, dh Fehler, die bei regelmäßiger Verwendung nicht auftreten. Ich weiß nicht, wie diese Regel für Python gilt, da StopIteration nach dieser Regel nicht existieren sollte.
quelle
Persönlich neige ich zur zweiten Methode (aber mit
has_key
):Auf diese Weise besteht jede Zuweisungsoperation nur aus zwei Zeilen (anstelle von 4 mit try / exception), und alle Ausnahmen, die ausgelöst werden, sind echte Fehler oder Dinge, die Sie verpasst haben (anstatt nur zu versuchen, auf Schlüssel zuzugreifen, die nicht vorhanden sind). .
Wie sich herausstellt (siehe die Kommentare zu Ihrer Frage),
has_key
ist es veraltet - also denke ich, es ist besser geschrieben alsquelle
Ab
Python 3.8
dem Start und der Einführung von Zuweisungsausdrücken (PEP 572) (:=
Operator) können wir den BedingungswertdictB.get('hello', None)
in einer Variablenvalue
erfassen, um zu überprüfen, ob dies nicht der Fall istNone
(dadict.get('hello', None)
entweder der zugehörige Wert oder zurückgegeben wirdNone
), und ihn dann im Hauptteil von zu verwenden die Bedingung:quelle
Obwohl die Betonung der akzeptierten Antwort auf das Prinzip "Schau, bevor du springst" für die meisten Sprachen gilt, ist möglicherweise mehr Python der erste Ansatz, der auf den Python-Prinzipien basiert. Ganz zu schweigen davon, dass es sich bei Python um einen legitimen Codierungsstil handelt. Wichtig ist, dass Sie den try-Block außer im richtigen Kontext verwenden und die Best Practices befolgen. Z.B. zu viele Dinge in einem try-Block tun, eine sehr breite Ausnahme abfangen oder schlimmer noch - die bloße Ausnahmeklausel usw.
Siehe die Python-Dokumentreferenz hier .
Auch dieser Blog von Brett, einem der Hauptentwickler, geht kurz darauf ein.
Schaue andere SO Diskussion hier :
quelle