当前位置: 首页 > 面试题库 >

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

赵夕
2023-03-14
问题内容

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



 类似资料:
  • 问题内容: 似乎对此产生了很多困惑和不同意见([1]和其他来源),究竟会产生深拷贝还是浅拷贝。 该测试表明该副本很深: 该测试表明该副本较浅: 解决方案是否仅是制作顶层维度的深层副本,而其他维度是浅层副本?真相是什么? 问题答案: 它产生一个浅表副本,即一个包含“旧”引用的 新 数组(指向相同的对象,这些对象没有被复制)。 特别是,如果您有嵌套数组,则不会复制这些数组。您将得到一个新数组,其“顶级

  • 我不确定以下内容是否会导致深度复制或浅复制? 有没有简单快速的方法可以深度复制字符串数组?

  • 本文向大家介绍Python中的复制操作及copy模块中的浅拷贝与深拷贝方法,包括了Python中的复制操作及copy模块中的浅拷贝与深拷贝方法的使用技巧和注意事项,需要的朋友参考一下 程序中常常需要复制一个对象, 按思路应该是这样的 已经复制好了,但是现在得改变一下第一个元素的值把它改成5 我改变了b的第一个元素的值,但是a的值也改变了,这是因为python中的=是引用.a和b指向的是相同的列表,

  • 本文向大家介绍深拷贝与 浅拷贝的区别?相关面试题,主要包含被问及深拷贝与 浅拷贝的区别?时的应答技巧和注意事项,需要的朋友参考一下 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

  • 本文向大家介绍什么是浅拷贝?它与C#中的深拷贝有何不同?,包括了什么是浅拷贝?它与C#中的深拷贝有何不同?的使用技巧和注意事项,需要的朋友参考一下 浅拷贝- 对象的浅表副本将复制“主”对象,但不复制内部对象。 “内部对象”在原始对象及其副本之间共享。 浅表副本的问题在于两个对象不是独立的。如果修改一个对象,则更改将反映在另一个对象中。 深度复制- 深层副本是对象的完全独立的副本。如果我们复制对象,

  • 本文向大家介绍java 深拷贝与浅拷贝机制详解,包括了java 深拷贝与浅拷贝机制详解的使用技巧和注意事项,需要的朋友参考一下  java 深拷贝与浅拷贝机制详解 概要: 在Java中,拷贝分为深拷贝和浅拷贝两种。java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定义的clone方法为深拷贝。 (一)Object中clone方法 如果