Python中拷贝是有深度的!

列表的拷贝

开始学习Python的时候我们应该在很多地方听到或学到这样一个问题,就是s = l[:],s(列表)可以实现l(列表)的拷贝:

l = [1, 3, 6]
s = l[:]
print(s, l is s)

结果为:

[1, 3, 6] False

显而易见,我们得到了l的一个副本,就是l与s只是值相同。我们可以测试下:

s[0] = 99
print(l, s)

结果为:

[1, 3, 6] [99, 3, 6]

就这个例子来说我们实现了拷贝。但是!并不是l[:]就能实现拷贝,这是由Python拷贝的深度决定的,举个例子:

l = [[1, 3, 8], 6, 7]
s = l[:]
print(l is s, l[0] is s[0])

结果:

False True

显然我们实现了l的拷贝,但是却不能将嵌套在l内部的列表一起复制了。个人认为这就是拷贝深度的问题!我们看下带来的问题:

s[0][0] = -99
print(l, s)

嵌套的列表是没有能够被拷贝的,s对嵌套的列表修改其元素都会影响l中的嵌套列表

[[-99, 3, 8], 6, 7] [[-99, 3, 8], 6, 7]

我们拷贝的是嵌套列表的索引,除非我们打破这个索引!

s[0] = None # 这样原先的指向就断了,索引被拷贝的关系就不在了
print(l, s)

这点需要好好理解,拷贝索引和拷贝的深度同样重要!!

[[-99, 3, 8], 6, 7] [None, 6, 7]
  • 总结
  1. python默认浅拷贝,这样拷贝时优先拷贝索引,共用内存,节省空间!
  2. 如果你的目的是一定深度的拷贝,那么这个python自动优化就成了困扰。

实现深度拷贝

假设对于嵌套列表你需要实现完全意义上的拷贝,那么可以这么做:

from copy import deepcopy
l = [[1, 3, 8], 6, 7]
s = deepcopy(l)
s[0][0] = -99
print(l, s)

实现了深度的拷贝:

[[1, 3, 8], 6, 7] [[-99, 3, 8], 6, 7]
  • 我测试了自己3.8版本,list.copy()也能实现深度拷贝。
  • 个人感觉深度拷贝的理解有助于拷贝索引和如何打断索引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值