for k, v in d.iteritems():
if type(v) is dict:
for t, c in v.iteritems():
print "{0} : {1}".format(t, c)
Ich versuche, ein Wörterbuch zu durchlaufen und alle Schlüsselwertpaare auszudrucken, bei denen der Wert kein verschachteltes Wörterbuch ist. Wenn der Wert ein Wörterbuch ist, möchte ich ihn aufrufen und seine Schlüsselwertpaare ausdrucken ... usw. Irgendeine Hilfe?
BEARBEITEN
Wie wäre es damit? Es wird immer noch nur eine Sache gedruckt.
def printDict(d):
for k, v in d.iteritems():
if type(v) is dict:
printDict(v)
else:
print "{0} : {1}".format(k, v)
Vollständiger Testfall
Wörterbuch:
{u'xml': {u'config': {u'portstatus': {u'status': u'good'}, u'target': u'1'},
u'port': u'11'}}
Ergebnis:
xml : {u'config': {u'portstatus': {u'status': u'good'}, u'target': u'1'}, u'port': u'11'}
python
dictionary
Takkun
quelle
quelle
dict
als Variablennamen. Tun Sie dies niemals (deshalb schlägt es fehl).Antworten:
Wie von Niklas gesagt, benötigen Sie eine Rekursion, dh Sie möchten eine Funktion zum Drucken Ihres Diktats definieren. Wenn der Wert ein Diktat ist, möchten Sie Ihre Druckfunktion mit diesem neuen Diktat aufrufen.
Etwas wie :
quelle
Es gibt potenzielle Probleme, wenn Sie Ihre eigene rekursive Implementierung oder das iterative Äquivalent mit Stack schreiben. Siehe dieses Beispiel:
Im normalen Sinne ist das verschachtelte Wörterbuch eine n-näre baumähnliche Datenstruktur. Die Definition schließt jedoch nicht die Möglichkeit einer Querkante oder sogar einer Hinterkante (also nicht länger eines Baumes) aus. Hier gilt beispielsweise key2.2 für das Wörterbuch von key1 , key2.3 zeigt auf das gesamte Wörterbuch (Hinterkante / Zyklus). Wenn es eine Hinterkante (Zyklus) gibt, wird der Stapel / die Rekursion unendlich ausgeführt.
Wenn Sie dieses Wörterbuch mit dieser Implementierung von Scharron drucken
Sie würden diesen Fehler sehen:
Gleiches gilt für die Implementierung von senderle .
Ebenso erhalten Sie mit dieser Implementierung eine Endlosschleife von Fred Foo :
Python erkennt jedoch tatsächlich Zyklen im verschachtelten Wörterbuch:
"{...}" ist der Ort, an dem ein Zyklus erkannt wird.
Wie von Moondra gefordert, ist dies eine Möglichkeit, Zyklen (DFS) zu vermeiden:
quelle
def myprint(d): stack = d.items() visited = set() while stack: k, v = stack.pop() if isinstance(v, dict): if k not in visited: stack.extend(v.iteritems()) else: print("%s: %s" % (k, v)) visited.add(k)
list(d.items())
alsd.items()
Rückgabe eine Ansicht, keine Liste, und verwenden Siev.items()
stattdessenv.iteritems()
Da a
dict
iterierbar ist, können Sie die klassische iterierbare Formel für verschachtelte Container mit nur wenigen geringfügigen Änderungen auf dieses Problem anwenden . Hier ist eine Python 2-Version (siehe unten für 3):Prüfung:
In Python 2 ist es möglicherweise möglich, einen benutzerdefinierten Benutzer zu erstellen
Mapping
, der als qualifiziert ist,Mapping
aber keinen enthältiteritems
. In diesem Fall schlägt dies fehl. Die Dokumente geben nicht an, dassiteritems
dies für a erforderlich istMapping
. Andererseits gibt die Quelle denMapping
Typen eineiteritems
Methode. Also für benutzerdefinierteMappings
, voncollections.Mapping
explizit nur für den Fall erben .In Python 3 müssen einige Verbesserungen vorgenommen werden. Ab Python 3.3 leben abstrakte Basisklassen in
collections.abc
. Auscollections
Gründen der Abwärtskompatibilität bleiben sie ebenfalls vorhanden, aber es ist schöner, wenn unsere abstrakten Basisklassen in einem Namespace zusammengefasst sind. Das importiert alsoabc
auscollections
. Python 3.3 fügt hinzuyield from
, das genau für diese Art von Situationen entwickelt wurde. Dies ist kein leerer syntaktischer Zucker; Dies kann zu schnellerem Code und sinnvolleren Interaktionen mit Coroutinen führen .quelle
isinstance(item, collections.Iterable)
ist keine Garantie fürhasattr(item, "iteritems")
. Überprüfencollections.Mapping
ist besser.Iterable
diese Lösung allgemeiner machen würde , wobei ich vergaß, dass Iterables offensichtlich nicht unbedingt vorhanden sinditeritems
.yield from
Syntax verwendet.Alternative iterative Lösung:
quelle
list
) durch einedeque
oder sogar eine Prioritätswarteschlange ersetzt wird.Etwas andere Version, die ich geschrieben habe und die die Schlüssel auf dem Weg dorthin verfolgt
Auf Ihren Daten wird gedruckt
Es ist auch einfach, es zu ändern, um das Präfix als Tupel von Schlüsseln und nicht als Zeichenfolge zu verfolgen, wenn Sie es auf diese Weise benötigen.
quelle
Hier ist eine pythonische Methode. Mit dieser Funktion können Sie das Schlüssel-Wert-Paar in allen Ebenen durchlaufen. Es speichert nicht das Ganze in der Erinnerung, sondern geht durch das Diktat, während Sie es durchlaufen
Druckt
quelle
Iterative Lösung als Alternative:
quelle
O(depth)
für die rekursive Lösung. Das gleiche gilt für diese Version, wenn ich richtig denke).iters
als expliziter Stapel verwendet, sodass der Big-O-Speicherverbrauch gleich ist, oder fehlt mir etwas?Eine alternative Lösung für die Arbeit mit Listen, die auf der Lösung von Scharron basieren
quelle
Ich verwende den folgenden Code, um alle Werte eines verschachtelten Wörterbuchs zu drucken, wobei berücksichtigt wird, wo der Wert eine Liste mit Wörterbüchern sein kann. Dies war nützlich für mich, wenn ich eine JSON-Datei in ein Wörterbuch analysierte und schnell überprüfen musste, ob einer ihrer Werte vorhanden ist
None
.Ausgabe:
quelle
Hier ist eine modifizierte Version von Fred Foos Antwort für Python 2. In der ursprünglichen Antwort wird nur die tiefste Verschachtelungsebene ausgegeben. Wenn Sie die Schlüssel als Listen ausgeben, können Sie die Schlüssel für alle Ebenen behalten. Um sie zu referenzieren, müssen Sie jedoch auf eine Liste von Listen verweisen.
Hier ist die Funktion:
So verweisen Sie auf die Schlüssel:
für ein dreistufiges Wörterbuch.
Sie müssen die Anzahl der Ebenen kennen, bevor Sie auf mehrere Schlüssel zugreifen können, und die Anzahl der Ebenen sollte konstant sein (es kann möglich sein, ein kleines Skript hinzuzufügen, um die Anzahl der Verschachtelungsebenen beim Durchlaufen von Werten zu überprüfen, aber ich habe es nicht getan noch angeschaut).
quelle
Ich finde diesen Ansatz etwas flexibler. Hier stellen Sie lediglich eine Generatorfunktion bereit, die Schlüssel- und Wertepaare ausgibt und einfach erweitert werden kann, um auch über Listen zu iterieren.
Dann können Sie Ihre eigene
myprint
Funktion schreiben und dann diese Schlüsselwertpaare drucken.Ein Test:
Ausgabe:
Ich habe dies auf Python 3.6 getestet.
quelle
Diese Antworten funktionieren nur für zwei Ebenen von Unterwörterbüchern. Für mehr versuchen Sie dies:
quelle