【问题标题】:Is creating a new list object via multiplication by one with an existing list equivalent to making a deep copy?是否通过将现有列表乘以一来创建新的列表对象,是否相当于进行深层复制?
【发布时间】:2018-07-27 00:56:34
【问题描述】:

例如,假设我想对列表 a 进行深层复制,名为 b

a = [1,2,3,4,5]

两者有什么区别:

import copy
b = copy.deepcopy(a)

和:

b = a*1  

在这两种情况下,我都创建了一个新对象(即id(a) == id(b)False),那么我应该了解哪些实际差异?谢谢!

【问题讨论】:

  • 是的。一个是深拷贝,另一个是浅拷贝。在这种特定情况下没有区别,但如果你有可变对象,这可能会导致意想不到的结果
  • 谢谢,有道理。因此,在制作可变对象容器的副本时,差异会变得很明显。

标签: python list deep-copy


【解决方案1】:

不,它们不相等。乘法运算符只做一个浅拷贝。深拷贝意味着列表中的引用也被复制(即创建新的引用),而浅拷贝只制作顶级引用的新副本,而不是其中的引用,如下所示:

import copy
a = [[],[]]
b = copy.deepcopy(a)
c = a * 1
for i, v in enumerate(a):
    print(id(v), id(b[i]), id(c[i]))

这个输出:

31231832 31261480 31231832
31260800 31261400 31260800

【讨论】:

  • 在这种情况下,使用乘法运算符是否与进行浅拷贝相同?有什么理由我想改用 b = copy.copy(a) 吗?谢谢!
  • 使用b = copy.copy(a) 使其更具可读性,但也略显冗长。制作浅拷贝的一种更常见的 Pythonic 方法是使用 b = a[:]
  • @trillian 不,除了清晰度。对于列表,您通常只使用my_list.copy()。一个更标准的成语只是my_list[:],pythonistas 会理解。我觉得my_list*1 比较晦涩。
  • @ juanpa.arrivillaga,是的,我同意my_list*1 更加晦涩难懂,事实上,我的问题是在试图理解别人的代码时出现的,其中充满了my_list*1 语法!
  • 我正在查看的代码有以下许多实例:a=np.array([[1,2,3,4,5],[1,2,3,4,5]])b=a[:]*1。在这种情况下,乘法发生在容器的内容上,我们必须相当于一个深拷贝,不是吗?
猜你喜欢
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2021-09-30
相关资源
最近更新 更多