浅拷贝和深拷贝
# 列表与字典的拷贝
# 已有列表的引用
对于已有的列表的引用,新的列表名也是指向堆区中已有列表的内存空间。
例如下面例子,因为是可变类型,二者分隔不开,list1列表修改,list2列表也会跟着改,因为他们指向的是同一个列表的内存地址,所以不能称之为拷贝。
list1 = [1, 2, 3]
list2 = list1
1
2
2
如果要复制一份列表进行改操作,又不想影响原列表,就需要拷贝一份原列表,产生一个新列表,并让原列表和新列表完全独立开。
# 浅copy
[新列表名] = [原列表名].copy()
浅copy是把原列表空间和其索引对应的第一层值的内存空间,完全拷贝一份。
新列表名会指向复制出来的列表的内存地址。但如果列表空间中还有列表,由于会拷贝一样的内存空间,所以对于嵌套列表的复制是不分隔的。
元素是不可变类型时,完全没有问题。但如果元素中有可变类型,列表、字典等,由于其列表元素是指向其列表的堆区内存地址。
所以如果嵌套列表元素的值被修改,则两个原列表和新列表都会受影响。也就是没有独立开可变类型的元素。
list2 = list1.copy()
1
# 深copy
from copy import deepcopy
[新列表名] = deepcopy(原列表名)
如果想要copy得到的新列表与原列表完全独立开,包括可变类型,就需要用到deepcopy函数进行深拷贝。
deepcopy函数会针对列表类型的元素,复制一份并产生一个新的内存地址,然后替换原位置的列表。这样就将列表或字典类型的元素,也独立出来了,对其进行修改,也就不会影响原列表了。
from copy import deepcopy
list2=deepcopy(list1)
1
2
2