列表的拷贝
开始学习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]
- 总结
- python默认
浅拷贝
,这样拷贝时优先拷贝索引,共用内存,节省空间! - 如果你的目的是一定深度的拷贝,那么这个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()
也能实现深度拷贝。 - 个人感觉深度拷贝的理解有助于拷贝索引和如何打断索引。
来源:CSDN
作者:码码的哈士奇
链接:https://blog.csdn.net/qq_35189715/article/details/104641619