浅拷贝,深层拷贝和正常赋值操作的区别究竟是什么?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)
import copy

a=”deepak”
b=1,2,3,4
c=[1,2,3,4]
d={1:10,2:20,3:30}

a1=copy.copy(a)
b1=copy.copy(b)
c1=copy.copy(c)
d1=copy.copy(d)


print "immutable - id(a)==id(a1)",id(a)==id(a1)
print "immutable   - id(b)==id(b1)",id(b)==id(b1)
print "mutable - id(c)==id(c1)",id(c)==id(c1)
print "mutable   - id(d)==id(d1)",id(d)==id(d1)

我得到以下结果 -

immutable - id(a)==id(a1) True
immutable   - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable   - id(d)==id(d1) False

如果我执行deepcopy -

a1=copy.deepcopy(a)
b1=copy.deepcopy(b)
c1=copy.deepcopy(c)
d1=copy.deepcopy(d)

结果是一样的 -

immutable - id(a)==id(a1) True
immutable   - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable   - id(d)==id(d1) False

如果我从事分派业务 -

a1=a
b1=b
c1=c
d1=d

那么结果是 -

immutable - id(a)==id(a1) True
immutable   - id(b)==id(b1) True
mutable - id(c)==id(c1) True
mutable   - id(d)==id(d1) True

有人可以解释一下这些副本究竟有什么区别吗?它与可变和不可变对象有关吗?如果是这样,你可以向我解释一下吗?

提问于
用户回答回答于

普通的赋值操作将简单地将新变量指向现有对象。该文档解释了浅层和深层副本之间的区别:

浅层和深层复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)相关:

  • 浅拷贝构造一个新的复合对象,然后(尽可能)将引用插入到原始对象中。
  • 深层副本构造一个新的复合对象,然后递归地将副本插入到原始对象中找到的对象。

这里有一点示范:

import copy

a = [1, 2, 3]
b = [4, 5, 6]
c = [a, b]

使用正常的分配操作来复制:

d = c

print id(c) == id(d)          # True - d is the same object as c
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]

使用浅拷贝:

d = copy.copy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]

使用深层复制:

d = copy.deepcopy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # False - d[0] is now a new object
用户回答回答于

对于不可变的对象,不需要复制,因为数据永远不会改变,所以Python使用相同的数据; ID总是一样的。对于可变对象,由于它们可能会发生变化,[浅]副本会创建一个新对象。

深度复制与嵌套结构有关。如果你有列表的列表,然后深层copies复制嵌套列表,所以它是一个递归副本。只需复制,你有一个新的外部列表,但内部列表是引用。

扫码关注云+社区