Python 中的深拷贝deepcopy与浅拷贝copy

Python中的赋值语句不会创建一个新对象,它们只是将一个新的变量名称指向原来的对象。

In [1]: a = [1,2,3]
In [2]: b = a

In [3]: b
Out[3]: [1, 2, 3]

In [4]: b is a
Out[4]: True

此时,如果原对象a发生变化, 变量b也同步受到影响。

In [5]: a.append(4)

In [6]: b
Out[6]: [1, 2, 3, 4]

制作拷贝

如果想要生成一个新的对象, 可以使用构造函数

In [1]: a = [1,2,3]
In [2]: b = list(a)

In [3]: b
Out[3]: [1, 2, 3]

In [4]: b is a
Out[4]: False

使用copy函数

In [1]: from copy import copy
In [2]: a = [1,2,3]

In [3]: b = copy(a)
In [4]: b is a
Out[4]: False

对于元素都是不可变的对象, 这样使用没有问题, 如果列表a中的元素包含其他可变对象, 浅拷贝只是在复制的列表中再次被引用。

In [1]: from copy import copy
In [2]: a = [1,2,3]
In [3]: sa = [a, [4, 5, 6]]

In [4]: sb = copy(sa)
In [5]: sb
Out[5]: [[1, 2, 3], [4, 5, 6]]

In [6]: a.append(4)
In [7]: sb
Out[7]: [[1, 2, 3, 4], [4, 5, 6]]

如上例代码中所示, sa是一个二维数组, sb是sa的一个浅拷贝副本, 当对sa中的第一个元素a调用append对a数据进行修改。 同样影响到了sb列表的值。

制作深拷贝

使用copy模块中的deepcopy, 可以解决这个问题。deepcoyp创建的对象的副本将递归克隆子对象。克隆完全独立于原始副本。

In [1]: from copy import deepcopy
In [2]: a = [1,2,3]
In [3]: sa = [a, [4, 5, 6]]

In [4]: sb = deepcopy(sa)
In [5]: sb
Out[5]: [[1, 2, 3], [4, 5, 6]]

In [6]: a.append(4)
In [7]: sb
Out[7]: [[1, 2, 3], [4, 5, 6]]

总结:

  1. 赋值语句只是增加对原对象的引用
  2. 制作对象的浅拷贝不会克隆子对象。因此,副本并不完全独立于原件。
  3. 对象的深层副本将递归克隆子对象。克隆完全独立于原始副本,但创建深层副本的速度较慢。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值