2017-07-27 59 views
1

我有很多名單裏面有很多字典。我只是分配給外部列表中的一個列表中的一個字典。但它會導致分配給外部列表中所有列表中的所有字典。列表分配中的字典導致奇怪的輸出

代碼:

CL=3*[0] 
DL=4*[0] 
di= { 
    'A':[], 
    'B':[], 
    'C':CL, 
    'D':DL 
    } 
R=[[],[]] 
R[0].append(di) 
R[1].append(di) 

def func(dd): 
    dd[0][0]['A'].append("BANANA") 
    dd[0][0]['B'].append("ELEPHANT") 
    dd[0][0]['C'][0]='BLUE' 
    dd[0][0]['D'][3]='ROCK' 
    dd[0][0]['D'][2]=1111 

print(R[0]) 
print(R[1]) 

print("\n") 

func(R) 

print(R[0]) 
print(R[1]) 

輸出:

[{'A': [], 'C': [0, 0, 0], 'B': [], 'D': [0, 0, 0, 0]}]                          
[{'A': [], 'C': [0, 0, 0], 'B': [], 'D': [0, 0, 0, 0]}]                          


[{'A': ['BANANA'], 'C': ['BLUE', 0, 0], 'B': ['ELEPHANT'], 'D': [0, 0, 1111, 'ROCK']}]                  
[{'A': ['BANANA'], 'C': ['BLUE', 0, 0], 'B': ['ELEPHANT'], 'D': [0, 0, 1111, 'ROCK']}] 

正如你所看到的,即使我賦值到字典中的第一個列表外列表(FUNC()操作只有在dd [0] ..),這兩個列表被分配。

我的索引編制有任何錯誤嗎?爲什麼會發生?

+1

R [0]和R [1]持有相同的字典,而不是初始的詞典的兩個單獨的副本。請參閱http://lucumr.pocoo.org/2011/7/9/python-and-pola/#pass-by-what-exactly – TheoretiCAL

+0

您可能會發現這篇文章有幫助:[關於Python名稱和值的事實和神話]( http://nedbatchelder.com/text/names.html),這是由SO經驗豐富的Ned Batchelder編寫的。 –

回答

2

代碼

R[0].append(di) 
R[1].append(di) 

將由參考diR。這意味着R[0]R[1]都指向相同的基礎對象。因此,改變一個改變底層對象,並因此改變兩者。

+0

嗨..感謝您的回答....但請問您能解釋我該如何解決這個問題? – nPab

+0

@nPab​​,亞歷克斯霍爾有一種方法來解決你的代碼在他的答案。我建議這種方法。 –

3
di= { 
    'A':[], 
    'B':[], 
    'C':CL, 
    'D':DL 
    } 
R=[[],[]] 
R[0].append(di) 
R[1].append(di) 

didididi的每次使用都不會創建單獨的副本。只有一個di,所以R[0][0]R[1][[0],並且所有更改都顯示在相同的字典中。

要修復代碼:

from copy import deepcopy 
R[0].append(deepcopy(di)) 
R[1].append(deepcopy(di))