Angenommen, ich habe zwei Python-Wörterbücher - dictA
und dictB
. Ich muss herausfinden, ob es Schlüssel gibt, die in, dictB
aber nicht in vorhanden sind dictA
. Was ist der schnellste Weg?
Soll ich die Wörterbuchschlüssel in ein Set konvertieren und dann loslegen?
Interessiert daran, deine Gedanken zu kennen ...
Vielen Dank für Ihre Antworten.
Entschuldigung, dass ich meine Frage nicht richtig gestellt habe. Mein Szenario ist wie folgt: Ich habe einen, dictA
der dictB
mit einigen Schlüsseln identisch sein kann oder bei dem einige Schlüssel fehlen, dictB
oder der Wert einiger Schlüssel kann unterschiedlich sein, was auf den Wert des Schlüssels eingestellt werden muss dictA
.
Das Problem ist, dass das Wörterbuch keinen Standard hat und Werte haben kann, die diktiert werden können.
Sagen
dictA={'key1':a, 'key2':b, 'key3':{'key11':cc, 'key12':dd}, 'key4':{'key111':{....}}}
dictB={'key1':a, 'key2:':newb, 'key3':{'key11':cc, 'key12':newdd, 'key13':ee}.......
Der Wert für 'key2' muss also auf den neuen Wert zurückgesetzt und 'key13' innerhalb des Diktats hinzugefügt werden. Der Schlüsselwert hat kein festes Format. Es kann ein einfacher Wert oder ein Diktat oder ein Diktat des Diktats sein.
quelle
def update(self, new_dict): self.__init__(new_dict, self.current_dict)
oder ähnlichem, damit Sie einen rollierenden Vergleich durchführen könnenDictDiffer
Klasse ist eine zustandslose Klasse und könnte eine Funktion sein. Diechanged
undunchanged
-Werte können in derselben Schleife berechnet werden. Diese beiden Funktionen könnten alist
anstelle von a zurückgeben,set
was sicherlich günstiger ist. Für einen umfassenden Vergleich können Sie sich das Unit-Test-Framework ansehen : docs.python.org/2/library/unittest.html. Befolgen Sie einfach dieassertDictEqual
Methode im Quellcode.set(dictb)
ist wahrscheinlich besser alsset(dictb.keys())
.Für den Fall, dass Sie den Unterschied rekursiv möchten, habe ich ein Paket für Python geschrieben: https://github.com/seperman/deepdiff
Installation
Von PyPi installieren:
Anwendungsbeispiel
Importieren
Das gleiche Objekt wird leer zurückgegeben
Der Typ eines Elements hat sich geändert
Der Wert eines Artikels hat sich geändert
Artikel hinzugefügt und / oder entfernt
String Unterschied
Saitendifferenz 2
Typänderung
Listenunterschied
Listenunterschied 2:
Listenunterschiede ohne Berücksichtigung von Reihenfolge oder Duplikaten: (mit denselben Wörterbüchern wie oben)
Liste mit Wörterbuch:
Sets:
Benannte Tupel:
Benutzerdefinierte Objekte:
Objektattribut hinzugefügt:
quelle
ignore_order=True
. Sie finden die Dokumente unter deepdiff.readthedocs.io/en/latest/diff.htmlIch bin mir nicht sicher, ob es "schnell" ist oder nicht, aber normalerweise kann man das tun
quelle
dicta
unddictb
da er wissen will, sind die Schlüssel davondictb
nicht indicta
.for key in dicta.keys():
=>for key in dicta:
Wie Alex Martelli schrieb, wenn Sie einfach überprüfen möchten, ob ein Schlüssel in B nicht in A ist,
any(True for k in dictB if k not in dictA)
wäre es der richtige Weg .So finden Sie die fehlenden Schlüssel:
Diese beiden Lösungen sind also ziemlich gleich schnell.
quelle
any(k not in dictA for k in dictB)
Wenn Sie wirklich genau das meinen, was Sie sagen (dass Sie nur herausfinden müssen, WENN "es Schlüssel gibt" in B und nicht in A, nicht WELCHE sind diese, wenn überhaupt), sollte der schnellste Weg sein:
Wenn Sie tatsächlich herausfinden müssen, WELCHE SCHLÜSSEL, falls vorhanden, in B und nicht in A sind und nicht nur "WENN", gibt es solche Schlüssel, dann sind vorhandene Antworten durchaus angemessen (aber ich schlage in zukünftigen Fragen mehr Präzision vor, wenn dies der Fall ist in der Tat was du meinst ;-).
quelle
Verwendung
set()
:quelle
set(d)
gibt bereits nur die Schlüssel zurück, so dass Sie tun könnenset(da).intersection(db)
Die Top-Antwort von hughdbrown schlägt vor, einen Satzunterschied zu verwenden, was definitiv der beste Ansatz ist:
Das Problem mit diesem Code ist, dass er zwei Listen erstellt, um nur zwei Sätze zu erstellen, sodass 4N Zeit und 2N Speicherplatz verschwendet werden. Es ist auch etwas komplizierter als es sein muss.
Normalerweise ist dies keine große Sache, aber wenn es so ist:
collections.abc.Mapping
hatKeysView
, das sich wie ein verhältSet
.Python 2
Gibt in Python 2
keys()
eine Liste der Schlüssel zurück, nicht aKeysView
. Sie müssen alsoviewkeys()
direkt danach fragen .Für Dual-Version 2.7 / 3.x-Code verwenden Sie hoffentlich
six
oder etwas Ähnliches, sodass Sie Folgendes verwenden könnensix.viewkeys(dictb)
:In 2.4-2.6 gibt es keine
KeysView
. Sie können jedoch zumindest die Kosten von 4N auf N senken, indem Sie Ihren linken Satz direkt aus einem Iterator heraus erstellen, anstatt zuerst eine Liste zu erstellen:Artikel
Sie müssen also wirklich nicht die Schlüssel vergleichen, sondern die Elemente. An
ItemsView
ist nur einSet
wenn die Werte wie Zeichenfolgen hashbar sind. Wenn ja, ist es einfach:Rekursiver Diff
Obwohl die Frage nicht direkt nach einem rekursiven Diff fragt, sind einige der Beispielwerte Dikte, und es scheint, dass die erwartete Ausgabe sie rekursiv diffundiert. Hier gibt es bereits mehrere Antworten, die zeigen, wie das geht.
quelle
Es gibt eine andere Frage im Stackoverflow zu diesem Argument, und ich muss zugeben, dass eine einfache Lösung erklärt wird: Die Datadiff-Bibliothek von Python hilft beim Drucken des Unterschieds zwischen zwei Wörterbüchern.
quelle
Hier ist eine Methode, die funktioniert, Schlüssel zulässt, die ausgewertet werden
False
, und dennoch einen Generatorausdruck verwendet , um nach Möglichkeit frühzeitig auszufallen. Es ist jedoch nicht außergewöhnlich hübsch.BEARBEITEN:
THC4k hat eine Antwort auf meinen Kommentar zu einer anderen Antwort gepostet. Hier ist eine bessere und schönere Möglichkeit, Folgendes zu tun:
Ich bin mir nicht sicher, wie mir das nie in den Sinn gekommen ist ...
quelle
any(k for k in dictB if k not in dictA)
die nicht dasselbe ist (für Falsey Keys). Überprüfen Sie den Bearbeitungsverlauf / die Zeitstempel.Dies ist eine alte Frage und stellt etwas weniger als das, was ich brauchte, sodass diese Antwort tatsächlich mehr löst als diese Frage. Die Antworten in dieser Frage haben mir geholfen, Folgendes zu lösen:
All dies in Kombination mit JSON bietet eine ziemlich leistungsstarke Unterstützung für Konfigurationsspeicher.
Die Lösung ( auch auf Github ):
quelle
Was ist mit Standard (vergleiche FULL Object)?
PyDev-> neues PyDev-Modul-> Modul: unittest
quelle
Wenn auf Python ≥ 2.7:
quelle
Hier ist eine Lösung für den tiefen Vergleich von 2 Wörterbuchschlüsseln:
quelle
Hier ist eine Lösung, die mehr als zwei Diktate vergleichen kann:
Anwendungsbeispiel:
quelle
Mein Rezept des symmetrischen Unterschieds zwischen zwei Wörterbüchern:
Und das Ergebnis ist:
quelle
Wie in anderen Antworten erwähnt, liefert unittest eine nette Ausgabe zum Vergleichen von Diktaten, aber in diesem Beispiel möchten wir nicht zuerst einen ganzen Test erstellen müssen.
Wenn Sie die unitteste Quelle herauskratzen, können Sie mit genau dem eine faire Lösung finden:
so
Ergebnisse in:
Wo:
Wie bei unittest besteht die einzige Einschränkung darin, dass die endgültige Zuordnung aufgrund des nachgestellten Kommas / der Klammer als Diff angesehen werden kann.
quelle
@Maxx hat eine ausgezeichnete Antwort. Verwenden Sie die
unittest
von Python bereitgestellten Tools:Dann können Sie überall in Ihrem Code anrufen:
Die resultierende Ausgabe sieht aus wie die Ausgabe von
diff
, indem die Wörterbücher mit jeder Zeile, die anders ist , hübsch gedruckt+
oder-
vorangestellt werden.quelle
Ich bin mir nicht sicher, ob es immer noch relevant ist, aber ich bin auf dieses Problem gestoßen. In meiner Situation musste ich nur ein Wörterbuch mit den Änderungen für alle verschachtelten Wörterbücher usw. zurückgeben. Es konnte keine gute Lösung gefunden werden, aber am Ende habe ich eine einfache Funktion geschrieben um dies zu tun . Hoffe das hilft,
quelle
Wenn Sie eine integrierte Lösung für einen vollständigen Vergleich mit beliebigen Diktatstrukturen wünschen, ist die Antwort von @ Maxx ein guter Anfang.
quelle
Basierend auf der Antwort von ghostdog74,
druckt einen anderen Wert von dicta aus
quelle
Versuchen Sie dies, um die Kreuzung zu finden, die Schlüssel, die sich in beiden Wörterbüchern befinden. Wenn Sie möchten, dass die Schlüssel im zweiten Wörterbuch nicht gefunden werden, verwenden Sie einfach die nicht in ...
quelle