如何制作复杂列表的完全不共享的副本?(深拷贝还不够)

发布于 2021-01-29 19:09:39

看一下下面的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专家请随时修改问题或标签以更好地表达此查询。)

关注者
0
被浏览
52
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    要将现有列表列表转换为不共享任何内容的列表,可以递归地复制列表。

    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数组,字典或用户类),则可能需要更改此设置。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看