2016-09-15 10 views
0

Ich habe eine Verpflichtung, in dem ich in eine Liste Objekt eingebettet Dictionary-Objekte mit doppelten Schlüssel erstellen müssen, so etwas wie dieses:Python erstellen Liste der Wörterbücher ohne Referenz

[{ "key": "ABC" },{ "key": "EFG" } ] 

I initialisiert eine Top-Level-Liste haben entschieden wie outer_list=[] und ein Platzhalter Wörterbuch Objekt wie dict_obj= {} zu leeren. Weiter halte ich Elemente meiner Liste mit den folgenden Schritten hinzu:

  1. { "key": "ABC" } weisen Sie dieses Objekt outer_list.append(dict_obj)
  2. Flush/Pop der Schlüssel/Artikel im Dictionary-Objekt mit der Liste dict_obj mit dict_obj["key"]="ABC"
  3. hinzufügen verwenden dict_obj.clear()
  4. Wiederholen Sie die Schritte 1 bis 3 auf der Grundlage der Anzahl der Schlüssel/Artikelkombinationen in meinen Daten

Ausgabe: t Er outer_list Objekt behält einen Verweis auf das Original dict_obj und wenn die dict_obj wird gespült oder ein neuer Schlüssel/Element hinzugefügt wird, ändert sich entsprechend. Also schließlich, ich am Ende mit dieser [{ "key": "EFG" },{ "key": "EFG" } ] statt [{ "key": "ABC" },{ "key": "EFG" } ]

Bitte führen Sie mich mit einigen Problemumgehungen, wenn möglich.

Antwort

1

Ich denke, es gibt zwei Möglichkeiten, die doppelte Referenzen zu vermeiden.

Die erste ist append eine Kopie des Wörterbuchs, anstelle einer Referenz darauf. dict Instanzen haben eine copy Methode, so ist dies einfach. ändern Sie einfach Ihren aktuellen append Aufruf:

outer_list.append(dict_obj.copy())` 

Die andere Option ist das gleiche dict_obj-Objekt zu verwenden, nicht immer, sondern ein separates Wörterbuch Objekt für jeden Eintrag erstellen. In dieser Version würden Sie Ihren Anruf dict_obj.clear() mit ersetzen:

dict_obj = {} 

Für den zweiten Ansatz, könnten Sie Dinge wählen eher neu zu ordnen, als einen gerade einzeiligen Ersatz zu tun. Sie könnten den Setup-Code an den Anfang der Schleife verschieben und die Reset-Logik am Ende der Schleife loswerden.

Das heißt, ändern Code, der wie folgt aussieht:

outer_list = [] 
dict_obj = {} 
for foo in whatever: 
    # add stuff to dict_obj 
    outer_list.append(dict_obj) 
    dict_obj.clear() 

An:

outer_list = [] 
for foo in whatever: 
    dict_obj = {} 
    # add stuff to dict_obj 
    outer_list.append(dict_obj) 

Wenn die Logik zur Erzeugung der inneren Wörterbücher zu berechnen ist einfach genug, könnten Sie sogar die ganze drehen Ding in ein Listenverständnis:

+0

Dank @Blckknght die erste Option, die Sie darauf hingewiesen funktioniert für mich. Ich muss die Schlüsselwerte in meiner Liste ansammeln, bis eine bestimmte Bedingung erfüllt ist, und sie dann zurücksetzen, sobald sie fertig ist (und für die nächste Iteration gehen).Ich hatte ein paar Probleme mit der Reihenfolge, den Listeninhalt zu leeren, aber das hatte hauptsächlich mit Daten zu tun. Ich erkannte auch, dass, wenn mein Schlüssel gleich ist, ich nicht einmal mein Wörterbuchobjekt dict_obj zurücksetzen muss, da der Schlüsselwert für dieselbe ID sowieso überschrieben würde. –

0

Folgendes sollte selbsterklärend sein:

# object reuse 
d = {} 
l = [] 
d['key'] = 'ABC' 
l.append(d) 
d.clear() 
print(l) # [{}] : cleared! 
d['key'] = 'EFG' 
l.append(d) 
print(l) # [{'key': 'EFG'}, {'key': 'EFG'}] 


# explicit creation of new objects 
d = {} 
l = [] 
d['key'] = 'ABC' 
l.append(d) 
print(l) 
d = {} 
d['key'] = 'EFG' 
l.append(d) 
print(l) 
Verwandte Themen