2014-12-23 40 views
0

我想更好地理解Python中的淺和深副本,特別是在涉及字典和列表時。列表和詞典的淺和深副本

比方說,我有一個字典列表,我想具體的鍵('a')的值複製到字典中的不同列表下不同的鍵名('x'):

list_dict = [{'a': 1}, {'a': 2}] 

dict1 = {} 
dict1['x'] = {} 
list1 = [] 

for entry in list_dict: 
    dict1['x'] = entry['a'] 
    list1.append(dict1) 

>>>print list1 
[{'x': 2}, {'x': 2}] 

顯然,並非什麼我想了。但是,我知道,我可以一個人字典創建一個淺表副本指定.copy()

for entry in list_dict: 
    dict1['x'] = entry['a'] 
    list1.append(dict1.copy()) 

>>>print list1 
[{'x': 1}, {'x': 2}] 

即使是膚淺,它的工作原理。現在,讓我們有點不同 - 我想不把它複製到dict1['x'],但dict1['x']['y']

for entry in list_dict: 
    dict1['x']['y'] = entry['a'] 
    list1.append(dict1.copy()) 

>>>print list1 
[{'x': {'y': 2}}, {'x': {'y': 2}}] 

回到原點 - 這是行不通的!所以,這是第一個問題 - 爲什麼它停止工作?

第二個問題是,爲什麼添加最後一行使它工作?

for entry in list_dict: 
    dict1['x']['y'] = entry['a'] 
    list1.append(dict1.copy()) 
    dict1['x'] = {} 

>>>print list1 
[{'x': {'y': 1}}, {'x': {'y': 2}}] 

非常感謝您提前!

P.S.我知道我可以做import copy然後copy.deepcopy(),但是我有興趣瞭解爲什麼當我添加更多級別的字典時爲什麼淺拷貝停止工作以及爲什麼「重置」字典的解決方法工作。

+1

爲什麼你認爲一個被稱爲淺而另一個深? –

+1

答案在文檔中https://docs.python.org/2/library/copy.html –

回答

2
for entry in list_dict: 
    dict1['x']['y'] = entry['a'] 
    list1.append(dict1.copy()) 

>>>print list1 
[{'x': {'y': 2}}, {'x': {'y': 2}}] 

回到原點 - 它不起作用!所以,這是第一個問題 - 爲什麼它停止工作?

因爲,你現在有詞典:

  1. {'x': {'y': 2}}
  2. {'x': {'y': 2}}
  3. {'y': 2}

    只有其中的兩個被 「複製」(1和2)。他們都引用3. 3的變化反映在1和2


而第二個問題是,爲什麼不把最後一行使其工作?

for entry in list_dict: 
    dict1['x']['y'] = entry['a'] 
    list1.append(dict1.copy()) 
    dict1['x'] = {} 

>>>print list1 
[{'x': {'y': 1}}, {'x': {'y': 2}}] 

因爲,你現在(使用{})每次迭代中創建一個新的字典,然後你改變它。您已經在初始化代碼中創建了第一個。您不會更改列表中舊字典的引用。只有一個即將插入。

未來提示:在這種情況下,爲了幫助您遵循代碼,最好的方法是使用調試模式並逐步執行程序。或者做懶人們做的事情,並在迭代過程中在對象中進行簡單打印,以查看它們的值。

+0

我想我得到了第一部分,謝謝!然而,仍然與第二個掙扎。爲什麼創建這個新的空字典不能清空淺拷貝?換句話說,爲什麼'dict1 ['x'] ['y'] = entry ['a']'改變'list1'的內容,但是'dict1 ['x'] = {}'不?僅僅是因爲第一個嵌套有兩層,而第二個嵌套沒有?但是,如果我做了'dict1 ['x'] = {'a':123}' - 結果是'y'值也得到保存以及... – ozhogin

+1

'dict1 ['x']' - > give我在''x''下的'dict1'中做了什麼。 ''dict1 ['x'] ['y]' - >給我鍵''x''中的'dict1'下的所有內容,然後在結果中給我關鍵字'''下的任何東西。所以,你在第一種情況下所做的直接改變了'dict1'。你在第二種情況下做的是改變一個對象'dict1'的引用。您可能還會注意到,雖然''x''是'dict1'中的一個鍵,''y''是'dict1' **中一個對象的鍵**。您可以使用'print dict1.keys()'在'dict1'中打印所有的鍵,並且您會看到'y'不在那裏。 –

相關問題