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

切片操作会为我提供深层还是浅层副本吗?

宋宏毅
2023-03-14
问题内容

在Python官方文档说,使用切片运算符和Python中的分配,使切片列表的浅表副本。

但是,例如,当我编写代码时:

o = [1, 2, 4, 5]
p = o[:]

当我写:

id(o)
id(p)

我得到不同的ID,并且追加一个列表不会反映在另一列表中。它不是在创建深拷贝,还是在我出问题的地方?


问题答案:

您正在创建 浅表 副本,因为嵌套值不会被复制,而只是被引用。一个 拷贝会建立一个列表中引用过的值的副本。

演示:

>>> lst = [{}]
>>> lst_copy = lst[:]
>>> lst_copy[0]['foo'] = 'bar'
>>> lst_copy.append(42)
>>> lst
[{'foo': 'bar'}]
>>> id(lst) == id(lst_copy)
False
>>> id(lst[0]) == id(lst_copy[0])
True

此处 嵌套的 字典不被复制;这两个列表仅引用了它。新元素42未共享。

请记住,Python中的所有内容都是一个对象,名称和列表元素仅是对这些对象的引用。列表的副本将创建一个新的外部列表,但是新列表仅接收对 完全相同的对象的
引用。

适当的深层副本会递归地为列表中包含的每个对象创建新副本:

>>> from copy import deepcopy
>>> lst_deepcopy = deepcopy(lst)
>>> id(lst_deepcopy[0]) == id(lst[0])
False


 类似资料:
  • 问题内容: 根据JAVA文档,当调用super.clone()时,将返回对象的浅表副本。在下面的代码中,我有两个对象 name 和 id ;和一个基本变量 num 。当在第一个对象上调用super.clone()方法时,除了预期的num副本外,它似乎还在创建对象的深层副本(名称和ID)。克隆对象obj之后,我更改了它的名称和id字段。如果正在制作浅表副本,则这些更改应反映在克隆的对象中。我对吗?

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

  • 问题内容: 我有一个不同的numpy数组的numpy数组,我想对数组进行深层复制。我发现以下内容: d是执行此操作的最佳方法吗?我错过了深层复制功能吗?与大小不同的数组中的每个元素进行交互的最佳方法是什么? 问题答案: 请随时在此处阅读更多内容。 哦,这是最简单的测试用例:

  • 问题内容: 这个问题已经在这里有了答案 : 9年前关闭。 可能重复: 如何克隆ArrayList并克隆其内容? 试图复制一个ArrayList。基础对象很简单,包含Strings,ints,BigDecimals,Dates和DateTime对象。如何确保对新ArrayList所做的修改不会反映在旧ArrayList中? 干杯,P 问题答案: 在添加对象之前先对其进行克隆。例如,代替 假设已正确覆

  • 问题内容: 无论Object.assign和对象传播只能做一浅合并。 问题的一个示例: 输出是您期望的。但是,如果我尝试这样做: 代替 你得到 x完全被覆盖,因为传播语法仅深入了一层。与相同。 有没有办法做到这一点? 问题答案: 有人知道ES6 / ES7规范中是否存在深度合并? 不,不是的。

  • 问题内容: 实现深层对象复制功能有点困难。您采取什么步骤来确保原始对象和克隆对象没有引用? 问题答案: 一种安全的方法是序列化对象,然后反序列化。这样可以确保所有内容都是全新的参考。 这是有关如何有效执行此操作的文章。 注意事项:类可能会覆盖序列化,这样就不会创建新实例,例如单例。如果您的课程不是可序列化的,那么这当然也行不通。