python deepcopy不删除使用*操作符扩展的列表中的内部引用?



我有以下代码。我将dicts列表(l1)扩展l1*3, deepcopy并分配给l2。现在,当我修改l2中的第一个元素时,l2中的其他相应元素也被修改了。那么deepcopy不删除*操作符在字典列表上创建的引用吗?

import copy
l1 = [{'a':1},{'b':2}]
l2 = copy.deepcopy(l1*3)
print(l2)
l2[0]['a'] = 7 # Why this changed ['a'] to 7 in all dicts in l2, even after deepcopy?
print(l2)

输出:

[{'a': 1}, {'b': 2}, {'a': 1}, {'b': 2}, {'a': 1}, {'b': 2}]
[{'a': 7}, {'b': 2}, {'a': 7}, {'b': 2}, {'a': 7}, {'b': 2}]

期望:(只有第一个元素应该修改)

[{'a': 1}, {'b': 2}, {'a': 1}, {'b': 2}, {'a': 1}, {'b': 2}]
[{'a': 7}, {'b': 2}, {'a': 1}, {'b': 2}, {'a': 1}, {'b': 2}]

我已经找到了以下解决方案来获得预期的输出:

l2 = [d.copy() for d in l1*3]

有人能解释一下为什么deepcopy在第一个代码中不起作用吗??

deepcopy有意地复制被复制结构中的任何别名引用。它维护一个memo字典,其中包含在当前复制操作期间已经复制的对象,当再次看到相同的对象时,它会为已经复制的对象插入别名。除此之外,这使得它在使用递归数据结构时是安全的(在这种情况下,非记忆的deepcopy将永远递归,直到耗尽内存并死亡)。

如果你想要单个元素不被使用别名,单独deepcopy它们,例如:

l2 = [copy.deepcopy(x) for x in l1*3]

分隔的deepcopy操作维护单独的记忆字典。

最新更新