2017-05-27 3 views
3

Ich habe eine Schleife, in der ich ein JSON-Objekt bearbeite und an eine Liste anschließe. Aber außerhalb der Schleife, wird der Wert aller alten Elemente auf die neue geändert
Meine Frage ist ähnlich wie this man hier, aber ich kann immer noch keine Lösung für mein Problem finden.list.append() ersetzt jede neue Variable

Das ist mein Code:

json_data = open(filepath).read() 
data = json.loads(json_data) 
dataNew=[] 

#opening file to write json 
with open(filepath2, 'w') as outfile: 
for i in range(50): 
    random_index_IntentNames = randint(0,len(intent_names)-1) 
    random_index_SessionIds = randint(0,len(session_id)-1) 
    timestamp = strftime("%Y-%m-%d %H:%M:%S", gmtime()) 
    data["result"]["metadata"]["intentName"] = intent_names[random_index_IntentNames] 
    data["sessionId"]=session_id[random_index_SessionIds] 
    data["timestamp"] = timestamp 
    dataNew.append(data) 
json.dump(dataNew, outfile, indent=2) 
+0

'Daten' ist ein Wörterbuch-Objekt. Sie hängen jedes Mal Referenzen auf das gleiche Objekt an. Wenn Sie also das Diktat ändern, wird die Änderung in der Liste widergespiegelt (jeder Eintrag in Ihrer Liste verweist auf das gleiche, einzelne Wörterbuch). Sie müssen tiefe Kopien des Diktats anhängen, damit sie nicht dasselbe Objekt im Speicher sind. Das ist im Grunde die Antwort, mit der Sie verbunden sind. – roganjosh

+0

Hallo @roganjosh. Ich bin ein Anfänger für Python-Programmierung, weshalb ich nicht genau verstehe. Wenn Sie eine Lösung haben, können Sie Änderungen an meinem Code vornehmen, damit er nach Bedarf funktioniert? –

Antwort

0

Ich konnte die Lösung selbst finden. Ich gab die Zuordnung von "Daten" innerhalb der Schleife und es funktionierte:

json_data = open(filepath).read() 
dataNew=[] 

#opening file to write json 
with open(filepath2, 'w') as outfile: 
for i in range(50): 
    random_index_IntentNames = randint(0,len(intent_names)-1) 
    random_index_SessionIds = randint(0,len(session_id)-1) 
    timestamp = strftime("%Y-%m-%d %H:%M:%S", gmtime()) 
    data = json.loads(json_data) 
    data["result"]["metadata"]["intentName"] = intent_names[random_index_IntentNames] 
    data["sessionId"]=session_id[random_index_SessionIds] 
    data["timestamp"] = timestamp 
    dataNew.append(data) 
json.dump(dataNew, outfile, indent=2) 
2

Jedes Element in der Liste ist nur ein Verweis auf ein einzelnes Objekt im Speicher. Ähnlich wie in Ihrer verknüpften Antwort, müssen Sie Kopien des Diktats anhängen.

import copy 

my_list = [] 

a = {1: 2, 3: 4} 
b = a # Referencing the same object 
c = copy.copy(a) # Creating a different object 

my_list.append(a) 
my_list.append(b) 
my_list.append(c) 

a[1] = 'hi' # Modify the dict, which will change both a and b, but not c 

print my_list 

Sie könnten in Is Python call-by-value or call-by-reference? Neither. zur weiteren Lektüre interessiert.

+0

Ich habe sowohl Kopie und Deepcopy verwendet, aber immer noch nicht funktioniert –

+0

@TonyMathew ist es schwer zu sagen, was das Problem ist. Mein Beispiel oben sollte repräsentativ sein für das, was wir in Ihrem Code sehen können. Wenn eine Kopie bei jeder Iteration nicht funktioniert, müssen Sie ein wiederholbares Beispiel angeben, das wir lokal ausführen können. – roganjosh

2

data ist ein dict, die mutable es bedeutet, und es ist Wert als Referenz übergeben wird, Sie [copy.deepcopy()] (https://docs.python.org/2/library/copy.html#copy.deepcopy) zu verwenden, wenn Sie möchten Ursprungsdaten halten, nicht stumm geschaltet:

from copy import deepcopy 
json_data = open(filepath).read() 
data = json.loads(json_data) 
dataNew=[] 

#opening file to write json 
with open(filepath2, 'w') as outfile: 
for i in range(50): 
    random_index_IntentNames = randint(0,len(intent_names)-1) 
    random_index_SessionIds = randint(0,len(session_id)-1) 
    timestamp = strftime("%Y-%m-%d %H:%M:%S", gmtime()) 
    # Create a shallow copy, modify it and append to new 
    new_data = deepcopy(data) 
    new_data["result"]["metadata"]["intentName"] = intent_names[random_index_IntentNames] 
    new_data["sessionId"]=session_id[random_index_SessionIds] 
    new_data["timestamp"] = timestamp 
    dataNew.append(new_data) 
json.dump(dataNew, outfile, indent=2) 

HINWEIS: Wenn data dosn't store veränderbare Elemente, die Sie dict.copy verwenden können, um zu vermeiden, Ursprungswert ändern.

Viel Glück!

+0

Es ersetzt immer noch die alten Elemente:/Können Sie eine Lösung dafür finden? –

+0

Ich habe copy.deepcopy() verwendet. Auch das funktioniert nicht:/ –

+0

@TonyMathew Ich habe meine Antwort aktualisiert, es sollte funktionieren, aber wenn es nicht funktioniert, bedeutet das, dass die Daten im anderen Teil Ihres Codes geändert werden. –

Verwandte Themen