copy就是复制一份,也就是所谓的抄一份。深浅copy其实就是完全复制一份,和部分复制一份的意思。
1.先看赋值运算
l1 = [1,2,3,['barry','alex']]
l2 = l1
l1[0] = 111
print(l1) # [111, 2, 3, ['barry', 'alex']]
print(l2) # [111, 2, 3, ['barry', 'alex']]
l1[3][0] = 'wusir'
print(l1) # [111, 2, 3, ['wusir', 'alex']]
print(l2) # [111, 2, 3, ['wusir', 'alex']]
对于赋值运算来说,l1和l2指向的是同一个内存地址,所以它们是完全一样的,任何一个变量对列表进行改变,剩下的那个变量在使用了列表之后,这个列表就是发生改变之后的列表
2.浅拷贝copy
值相同,不可变类型满足同一代码块缓存机制,可变类型内存地址都相同
# 同一代码块下
l1 = [1, '太白', True, (1,2,3), [22, 33]]
l2 = l1.copy()
print(id(l1), id(l2)) # 2713214468360 2713214524680
print(id(l1[-2]), id(l2[-2])) # 2547618888008 2547618888008
print(id(l1[-1]),id(l2[-1])) # 2547620322952 2547620322952
#不能同代码块下
>>> l1 = [1, '太白', True, (1, 2, 3), [22, 33]]
>>> l2 = l1.copy()
>>> print(id(l1), id(l2))
1477183162120 1477183162696
>>> print(id(l1[-2]), id(l2[-2]))
1477181814032 1477181814032
>>> print(id(l1[-1]), id(l2[-1]))
1477183162504 1477183162504
对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是列表中的元素与原列表中的元素是公用的(也就是说内存地址一致,一个改变的同时另一个也会跟着改变!!)
如果两元素或者多个元素指向同一内存地址,那么它们的值就是相同的,其中一个元素改变了,
那么因为它们的内存地址相同,所以其他的元素的值就跟着一起改变。
>>> l1 = [1,2,3,[22,444]]
>>> l2 = l1
>>> l1[0] = [4] # l1中[0]的内存地址与l2中的相同
>>> l1
[[4], 2, 3, [22, 444]]
>>> l2
[[4], 2, 3, [22, 444]]
>>> l1 + [22,333] # l1的内存地址跟l2的不同
[[4], 2, 3, [22, 444], 22, 333]
>>> l2
[[4], 2, 3, [22, 444]]
3.深拷贝deepcopy
要引入python标准库 copy
值相同,不可变类型满足小数据池,
可变类型内存地址都不相同
# 同一代码块下 不可变类型满足代码块缓存机制
import copy
l1 = [1, 'alex', True, (1,2,3), [22, 33]]
l2 = copy.deepcopy(l1)
print(id(l1), id(l2)) # 2788324482440 2788324483016
print(id(l1[0]),id(l2[0])) # 1470562768 1470562768
print(id(l1[-1]),id(l2[-1])) # 2788324482632 2788324482696
print(id(l1[-2]),id(l2[-2])) # 2788323047752 2788323047752
# 不同代码块下 不可变类型满足小数据池
>>> import copy
>>> l1 = [1, '太白', True, (1, 2, 3), [22, 33]]
>>> l2 = copy.deepcopy(l1)
>>> print(id(l1), id(l2))
1477183162824 1477183162632
>>> print(id(0), id(0))
1470562736 1470562736
>>> print(id(-2), id(-2))
1470562672 1470562672
>>> print(id(l1[-1]), id(l2[-1]))
1477183162120 1477183162312
深copy的特性就是将可变的数据类型在内存中重新创建一份,而不可变的数据类型则沿用之前的
对于深copy来说,列表是在内存中重新创建的,列表中的可变的数据类型就是重新创建的,
列表中的不可变的数据类型是公用的
l1 = [1, 2, 3, 4, ['alex']]
l2 = l1[::]
l1[-1].append(666)
print(l2) #[1, 2, 3, 4, ['alex', 666]]