更改一个字典值会更改所有值

时间:2012-11-21 17:10:37

标签: python list dictionary

我在Python Dictionary中看到一些不寻常的行为:

import numpy as np
td =[np.Inf, 2, 3]
a = {}
# First initialize contents of dictionary to a list of values
for k in range(10):
    a[k] = td

#now I want to access the contents to modify them based on certain criteria 
for k in range(10):
    c = a[k]
    c[0] = k
    a[k] = c

从此我可以预期每个字典键值的列表中的每个第一项都会根据(c [0] = k)进行更改,但是,最后得到的是字典的所有值都会更新到k的最后一个值:如

{0: [9, 2, 3], 1: [9, 2, 3], 2: [9, 2, 3], 3: [9, 2, 3], 
 4: [9, 2, 3], 5: [9, 2, 3], 6: [9, 2, 3], 7: [9, 2, 3], 
 8: [9, 2, 3], 9: [9, 2, 3]}

我遗漏了什么,或者字典定义中有什么问题? 我可以用不同的方式解决这个问题,以便我的代码能够运行,但我对字典类的行为方式感兴趣。

3 个答案:

答案 0 :(得分:9)

因为每个键都获得相同列表 ...要制作列表的浅表副本,请使用以下语法:

for k in range(10):
    a[k] = td[:] 

演示:

>>> d = {}
>>> el = [1, 2, 3]
>>> d[0] = el
>>> d[1] = el
>>> map(id, d.values())
[28358416, 28358416]

答案 1 :(得分:1)

这种情况正在发生,因为当您将值插入dict时,您不会插入全新的列表。您实际上是插入对同一旧列表的引用。因此,当您更改一个值时,实际上是在更改值指向的列表,因此也就是所有值指向的列表。

如果你真的想要为每个值单独列出,那么你最好在插入时制作一个浅表的列表副本,如下所示:

td =[np.Inf, 2, 3]
for k in range(10):
    a[k] = td[:] #making a new list out of the old one

现在,这将以您期望的方式运作

for k in range(10):
    c = a[k]
    c[0] = k
    a[k] = c

希望这有帮助

答案 2 :(得分:0)

当您在td行中引用a[k] = td时,您实际上是在对原始列表添加引用。无论引用哪个列表,都可以看到对该列表的任何修改。您需要使用the copy module来创建一个新列表(或在循环中为每个条目构建一个新列表):

for k in range(10):
    a[k] = [np.Inf, 2, 3]
相关问题