深浅copy其实就是完全复制一份还是部分复制一份的意思
赋值运算
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
li = [1, 2, 3, ["alex", 5]] lii = li print(li, id(li)) # [1, 2, 3, ['alex', 5]] 1613748156488 print(lii, id(lii)) # [1, 2, 3, ['alex', 5]] 1613748156488 li[0] = 4 print(li, id(li)) # [4, 2, 3, ['alex', 5]] 1613748156488 print(lii, id(lii)) # [4, 2, 3, ['alex', 5]] 1613748156488 li[-1][1] = 25 print(li, id(li)) # [4, 2, 3, ['alex', 25]] 1613748156488 print(lii, id(lii)) # [4, 2, 3, ['alex', 25]] 1613748156488
对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的。换句话说,l1,l2指向的是同一个列表,任何一个变量对列表进行改变,剩下那个变量在使用列表之后,这个列表就是发生改变之后的列表
浅拷贝copy
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 浅拷贝 copy # 同一代码块下 # l1 = [1, 2, [22, 33]] # l2 = l1.copy() # 浅copy # print(l1, id(l1)) # [1, 2, [22, 33]] 2178883823752 # print(l2, id(l2)) # [1, 2, [22, 33]] 2178764893768 # print(id(l1[0])) # 1842834496 # print(id(l2[0])) # 1842834496 # # print(id(l1[1])) # 1842834528 # print(id(l2[1])) # 1842834528 # print(id(l1[-1])) # 2178883880200 # print(id(l2[-1])) # 2178883880200 # # print("****************************************************") # # l1.append(888) # print(l1, id(l1)) # [1, 2, [22, 33], 888] 2178883823752 # print(l2, id(l2)) # [1, 2, [22, 33]] 2178764893768 l1 = [1, 2, [22, 33]] l2 = l1.copy() l1[-1].append(777) print(l1, id(l1)) # [1, 2, [22, 33, 777]] 2210650830920 print(l2, id(l2)) # [1, 2, [22, 33, 777]] 2210531831368 print(id(l1[-1])) # 2210650883272 print(id(l2[-1])) # 2210650883272 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来说,只是在内存中重新创建开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的
深拷贝deepcopy
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 同一代码块内 l1 = [1, 2, 3, [22, 33]] l2 = copy.deepcopy(l1) print(id(l1), id(l2)) # 2036809971784 2036690906696 l1.insert(0, "alex") print(l1, l2) # ['alex', 1, 2, 3, [22, 33]] [1, 2, 3, [22, 33]] l1[-1].append(666) # ['alex', 1, 2, 3, [22, 33, 666]] [1, 2, 3, [22, 33]] print(l1, l2) print(id(l1), id(l2)) # 2036809971784 2036690906696 l1 = [1, True, (1, 2, 3), [22, 33]] l2 = copy.deepcopy(l1) print(l1, id(l1)) # [1, True, (1, 2, 3), [22, 33]] 1459141589064 print(l2, id(l2)) # [1, True, (1, 2, 3), [22, 33]] 1459022523976 print(id(l1[0]), id(l1[1]), id(l1[2]), id(l1[-1])) # 1842834496 1842344096 1459022290376 1459141641416 print(id(l2[0]), id(l2[1]), id(l2[2]), id(l2[-1])) # 1842834496 1842344096 1459022290376 1459019844488 # 不同代码块下 >>> 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来说,列表是在内存中重新创建的,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的。
相关面试题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
l1 = [1, 2, 3, 4, ['alex']] l2 = l1[::] l1[-1].append(666) print(l1) # [1, 2, 3, 4, ['alex', 666]] print(l2) # [1, 2, 3, 4, ['alex', 666]] # 浅copy : list、dict: 嵌套的可变的数据类型是同一个 # 深copy : list、dict: 嵌套的可变的数据类型不是同一个