2017-07-27 62 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))