如何制作复杂列表的完全不共享的副本?(深拷贝还不够)
看一下下面的Python代码:
a = [1, 2, 3]
b = [4, 5, 6]
c = [[a, b], [b, a]] # [[[1, 2, 3], [4, 5, 6]], [[4, 5, 6], [1, 2, 3]]]
c[0][0].append(99) # [[[1, 2, 3, 99], [4, 5, 6]], [[4, 5, 6], [1, 2, 3, 99]]]
请注意,修改其中的一个元素如何c
在各处进行修改。也就是说,如果99
附加到c[0][0]
,它也会附加到c[1][1]
。我猜这是因为Python巧妙地为和
引用 了 同一对象 。(那是他们的 id() 相同。)c[0][0]``c[1][1]
__
问题: 是否可以做一些事情,c
以便可以安全地在本地修改其列表元素?上面仅是一个示例,我的实际问题列表更加复杂,但存在类似的问题。
(对上面格式不正确的问题深表歉意。Python专家请随时修改问题或标签以更好地表达此查询。)
-
要将现有列表列表转换为不共享任何内容的列表,可以递归地复制列表。
deepcopy
这是不够的,因为它将按原样复制结构,将 内部 引用保留为引用,而不是副本。def unshared_copy(inList): if isinstance(inList, list): return list( map(unshared_copy, inList) ) return inList alist = unshared_copy(your_function_returning_lists())
请注意,这假设数据以列表列表的形式返回(任意嵌套)。如果容器的类型不同(例如numpy数组,字典或用户类),则可能需要更改此设置。