我似乎遇到了一个问题,我正在使用dict
将一个模板列表复制到list()
中的多个键,这样我就可以专门为使用{dict
访问的给定列表更改值1}}键。但是,我似乎在操作复制列表的键的值。
list1 = [['x', 'y', 0],
['m', 'n', 0],
]
dict2 = {'first': list(list1),
'second': list(list1),
}
def attempt(arg):
dict_key = dict2[arg]
for each in dict_key:
each[2] += 1
attempt('first')
print dict2['first']
print dict2['second']
输出:
[['x', 'y', 1], ['m', 'n', 1]] # expect elems to contain 1
[['x', 'y', 1], ['m', 'n', 1]] # expect elems to contain 2
看起来list()实际上并没有创建一个实际的副本,但是行为更像是一个赋值,但这对我来说没有意义。有人可以解释一下吗?
答案 0 :(得分:3)
list()
确实制作副本......但它是浅副本。当您致电a = list(b)
时,a是一个全新的列表,但它指的是与b
相同的对象。如果这些对象本身就是列表,那么你还没有完成你想做的事。
要执行“2级”复制,您只需使用列表解析:
a = [list(x) for x in b]
要执行一个完全向下的副本(也处理棘手的情况,比如字符串由字符串组成),请使用stdlib中的deepcopy
函数。
为了调试这些事情,使用is
运算符或id
函数会有所帮助。例如:
>>> list1 = [['x', 'y', 0],
... ['m', 'n', 0],
... ]
>>> dict2 = {'first': list(list1),
... 'second': list(list1),
... }
>>> id(dict2['first'])
4398414856
>>> id(dict2['second'])
4398414920
>>> id(dict2['first'][0])
4378407688
>>> id(dict2['second'][0])
4378407688
您可以很容易地看到first
和second
是两个不同的列表......但它们具有相同的第一个元素。
或者,或者,在交互式可视化工具中运行您的代码,例如this one。