Ich habe ein verschachteltes Wörterbuch. Gibt es nur einen Weg, um Werte sicher herauszuholen?
try:
example_dict['key1']['key2']
except KeyError:
pass
Oder hat Python eine Methode wie get()
für verschachtelte Wörterbücher?
python
dictionary
methods
except
Arti
quelle
quelle
except keyerror:
Klausel jederzeit einen Standardwert angeben .Antworten:
Sie könnten
get
zweimal verwenden:Dies wird zurückgegeben,
None
wenn eines vorhanden istkey1
oderkey2
nicht.Beachten Sie, dass dies immer noch ein
AttributeError
ifexample_dict['key1']
auslösen kann, aber kein Diktat (oder ein diktatähnliches Objekt mit einerget
Methode) ist. Dertry..except
Code, den Sie gepostet haben, würdeTypeError
stattdessen ein if auslösenexample_dict['key1']
abonnierbar ist.Ein weiterer Unterschied besteht darin, dass die
try...except
Kurzschlüsse unmittelbar nach dem ersten fehlenden Schlüssel erfolgen. Die Anrufketteget
nicht.Wenn Sie die Syntax beibehalten möchten,
example_dict['key1']['key2']
aber nicht möchten, dass KeyErrors jemals ausgelöst wird, können Sie das Hasher-Rezept verwenden :Beachten Sie, dass dies einen leeren Hasher zurückgibt, wenn ein Schlüssel fehlt.
Da
Hasher
es sich um eine Unterklasse vondict
Ihnen handelt, können Sie einen Hasher genauso verwenden wie einendict
. Es stehen dieselben Methoden und Syntax zur Verfügung. Hashers behandeln fehlende Schlüssel nur unterschiedlich.Sie können eine reguläre
dict
in eineHasher
solche umwandeln :und konvertieren Sie ein
Hasher
in ein reguläresdict
genauso einfach:Eine andere Alternative besteht darin, die Hässlichkeit in einer Hilfsfunktion zu verbergen:
Der Rest Ihres Codes kann also relativ lesbar bleiben:
quelle
safeget
Methode ist in vielerlei Hinsicht nicht sehr sicher, da sie das ursprüngliche Wörterbuch überschreibt, was bedeutet, dass Sie solche Dinge nicht sicher tun könnensafeget(dct, 'a', 'b') or safeget(dct, 'a')
.safeget
überschreibt niemals das ursprüngliche Wörterbuch. Es wird entweder das ursprüngliche Wörterbuch, ein Wert aus dem ursprünglichen Wörterbuch oder zurückgegebenNone
.dct = dct[key]
neu zuweist einen neuen Wert der lokalen Variablendct
. Dies mutiert nicht das ursprüngliche Diktat (daher bleibt das ursprüngliche Diktat davon unberührtsafeget
). Wenn andererseits verwendetdct[key] = ...
worden wäre, wäre das ursprüngliche Diktat geändert worden. Mit anderen Worten, in Python sind Namen an Werte gebunden . Die Zuweisung eines neuen Werts zu einem Namen wirkt sich nicht auf den alten Wert aus (es sei denn, es gibt keine Verweise mehr auf den alten Wert. In diesem Fall (in CPython) wird der Müll gesammelt.)Sie können auch Python Reduce verwenden :
quelle
Durch die Kombination all dieser Antworten hier und kleiner Änderungen, die ich vorgenommen habe, halte ich diese Funktion für nützlich. Es ist sicher, schnell und leicht zu warten.
Beispiel:
quelle
deep_get({'a': 1}, "a.b")
gibtNone
aber ich würde eine ausnahme wieKeyError
oder etwas anderes erwarten .None
Raise KeyError
Aufbauend auf Yoavs Antwort ein noch sicherer Ansatz:
quelle
Eine rekursive Lösung. Es ist nicht das effizienteste, aber ich finde es etwas lesbarer als die anderen Beispiele und es basiert nicht auf functools.
Beispiel
Eine poliertere Version
quelle
Während der Reduktionsansatz ordentlich und kurz ist, denke ich, dass eine einfache Schleife leichter zu groken ist. Ich habe auch einen Standardparameter eingefügt.
Um zu verstehen, wie der reduzierte Einzeiler funktioniert, habe ich Folgendes getan. Aber letztendlich scheint mir der Loop-Ansatz intuitiver zu sein.
Verwendung
quelle
Ich schlage vor, Sie versuchen es
python-benedict
.Es ist ein
dict
Unterklasse, die Tastaturpfadunterstützung und vieles mehr bietet.Installation:
pip install python-benedict
Jetzt können Sie über den Schlüsselpfad auf verschachtelte Werte zugreifen :
oder greifen Sie über die Schlüsselliste auf verschachtelte Werte zu :
Es ist gut getestet und Open Source auf GitHub :
https://github.com/fabiocaccamo/python-benedict
quelle
d.get('a.b[0].c[-1]')
Eine einfache Klasse, die ein Diktat umschließen und basierend auf einem Schlüssel abrufen kann:
Beispielsweise:
Wenn der Schlüssel nicht vorhanden ist, wird er
None
standardmäßig zurückgegeben. Sie können dies mit einemdefault=
Schlüssel imFindDict
Wrapper überschreiben - zum Beispiel`:quelle
Für das Abrufen von Schlüsseln der zweiten Ebene können Sie Folgendes tun:
quelle
Nachdem ich dies gesehen hatte , um Attribute gründlich abzurufen, habe ich Folgendes ausgeführt, um verschachtelte
dict
Werte mithilfe der Punktnotation sicher abzurufen . Dies funktioniert bei mir, da meinedicts
Objekte deserialisiert sind und ich weiß, dass die Schlüsselnamen keine.
s enthalten . Außerdem kann ich in meinem Kontext einen falschen Fallback-Wert (None
) angeben , den ich nicht in meinen Daten habe, damit ich beim Aufrufen der Funktion das Muster try / exception vermeiden kann.quelle
fallback
wird in der Funktion nicht verwendet..
sep=','
Schlüsselwort arg hinzufügen, um es für bestimmte Bedingungen (Sep, Fallback) zu verallgemeinern. Und @denvar, wenn nach einer Sequenz des Reduzierensobj
vom Typ gesprochen wirdint
, dann löst obj [name] einen TypeError aus, den ich abfange. Wenn ich stattdessen obj.get (Name) oder obj.get (Name, Fallback) verwenden würde, würde dies einen AttributeError auslösen, so oder so müsste ich abfangen.Eine weitere Funktion für dasselbe gibt ebenfalls einen Booleschen Wert zurück, um darzustellen, ob der Schlüssel gefunden wurde oder nicht, und behandelt einige unerwartete Fehler.
Anwendungsbeispiel:
quelle
Sie können pydash verwenden:
https://pydash.readthedocs.io/en/latest/api.html
quelle
Eine Anpassung der Antwort von unutbu, die ich in meinem eigenen Code nützlich fand:
Es generiert einen Wörterbucheintrag für key1, wenn dieser Schlüssel noch nicht vorhanden ist, sodass Sie den KeyError vermeiden. Wenn Sie ein verschachteltes Wörterbuch erstellen möchten, das diese Schlüsselpaarung sowieso wie ich enthält, scheint dies die einfachste Lösung zu sein.
quelle
Da es vernünftig ist, einen Schlüsselfehler auszulösen, wenn einer der Schlüssel fehlt, können wir ihn nicht einmal überprüfen und so einfach erhalten:
quelle
Wenig Verbesserung zu
reduce
nähern, damit es mit Liste funktioniert. Verwenden Sie auch den Datenpfad als Zeichenfolge, die durch Punkte anstelle des Arrays geteilt wird.quelle
Eine Lösung, die ich verwendet habe und die dem Double Get ähnelt, aber zusätzlich die Möglichkeit bietet, einen TypeError mithilfe der if else-Logik zu vermeiden:
Je verschachtelter das Wörterbuch ist, desto umständlicher wird dies.
quelle
Für verschachtelte Wörterbuch- / JSON-Suchvorgänge können Sie dictor verwenden
pip install dictor
Objekt diktieren
Um Lonestars Gegenstände zu erhalten, geben Sie einfach einen durch Punkte getrennten Pfad an, d. h
Sie können einen Fallback-Wert angeben, falls sich der Schlüssel nicht im Pfad befindet
Es gibt unzählige weitere Optionen, die Sie tun können, z. B. das Groß- und Kleinschreibung von Buchstaben ignorieren und andere Zeichen als '.' als Pfadtrennzeichen
https://github.com/perfecto25/dictor
quelle
Ich habe diese Antwort wenig geändert . Ich habe hinzugefügt, um zu überprüfen, ob wir eine Liste mit Zahlen verwenden. Jetzt können wir es also auf jede Art und Weise verwenden.
deep_get(allTemp, [0], {})
oderdeep_get(getMinimalTemp, [0, minimalTemperatureKey], 26)
etc.quelle
Es gibt bereits viele gute Antworten, aber ich habe eine Funktion namens get ähnlich wie lodash get in JavaScript land entwickelt, die auch das Aufrufen von Listen nach Index unterstützt:
quelle