2017-05-27 54 views
3

我有一個循環,我在其中編輯json對象並將其附加到列表中。但是,外循環,所有舊元素的值被更改爲新的一個
我的問題是類似這裏this一個,但我仍然無法找到一個解決我的問題。list.append()將每個變量替換爲新的變量

這是我的代碼:

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

'data'是一個字典對象。每次添加對同一對象的引用,所以如果更改字典,則更改將反映在整個列表中(列表中的每個條目都指向相同的單個字典)。你需要附加dict的深層副本,以便它們不是內存中的同一個對象。這基本上就是你所說的答案。 – roganjosh

+0

嗨@roganjosh。我是Python編程的初學者,這就是爲什麼我不完全明白你的觀點。如果您有解決方案,您是否可以對我的代碼進行更改,以便按照要求工作? –

回答

0

我自己能找到解決方案。我給循環中的「數據」賦值,它的工作原理如下:

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

列表中的所有產品只是在內存中的單個對象的引用。與鏈接答案中發佈的內容類似,您需要附加字典副本。

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 

您可能會感興趣的Is Python call-by-value or call-by-reference? Neither.進一步閱讀。

+0

我已經使用了copy和deepcopy,但仍然不起作用 –

+0

@TonyMathew很難說出問題所在。我上面的例子應該代表我們可以在代碼中看到的內容。如果在每次迭代中複製都不起作用,那麼您需要提供一個可重複的示例,我們可以在本地運行。 – roganjosh

2

data是一個字典,這意味着它的mutable,它的值是通過引用傳遞,你必須使用[copy.deepcopy()] (https://docs.python.org/2/library/copy.html#copy.deepcopy)如果你想保持原點數據未靜音:

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) 

注意:如果data不存儲可變項目,您可以使用dict.copy以避免修改原始值。

祝你好運!

+0

它仍然取代舊的元素:/你能找到解決辦法嗎? –

+0

我已經使用copy.deepcopy()。即使這不工作︰/ –

+0

@TonyMathew我已經更新了我的答案,它應該工作,但是如果它不起作用,那麼意味着數據在您的代碼的其他部分被修改。 –