4.7 淺拷貝和深拷貝(只針對(duì)可變類(lèi)型:列表、字典、集合)
# 拷貝
lis1=[1,2,3,[4,5]] #可變:值變id不變
lis2=lis1 #最基本拷貝
print(f'操作前:id(lis1):{id(lis1)},lis1:{lis1}')
print(f'操作前:id(lis2):{id(lis2)},lis2:{lis2}')
print('-'*50)
lis1.append(5) #修改lis1,lis2也被修改
print(lis1)
print(lis2)
print('-'*50)
lis1[0]=0#修改lis1,lis2也被修改
print(lis1)
print(lis2)
print('-'*50)
lis1[0]=0#修改lis1,lis2也被修改
print(lis1)
print(lis2)
print('-'*50)
lis1[3].append(6)
print(lis1)
print(lis2)
print('-'*50)
print(f'操作后:id(lis1):{id(lis1)},lis1:{lis1}')
print(f'操作后:id(lis2):{id(lis2)},lis2:{lis2}')
操作前:id(lis1):2658013585664,lis1:[1, 2, 3, [4, 5]]
操作前:id(lis2):2658013585664,lis2:[1, 2, 3, [4, 5]]
--------------------------------------------------
[1, 2, 3, [4, 5], 5]
[1, 2, 3, [4, 5], 5]
--------------------------------------------------
[0, 2, 3, [4, 5], 5]
[0, 2, 3, [4, 5], 5]
--------------------------------------------------
[0, 2, 3, [4, 5], 5]
[0, 2, 3, [4, 5], 5]
--------------------------------------------------
[0, 2, 3, [4, 5, 6], 5]
[0, 2, 3, [4, 5, 6], 5]
--------------------------------------------------
操作后:id(lis1):2658013585664,lis1:[0, 2, 3, [4, 5, 6], 5]
操作后:id(lis2):2658013585664,lis2:[0, 2, 3, [4, 5, 6], 5]
4.7.1 淺拷貝
- lis1=[1,2,[3,4],6,7,8]
- lis2=copy.copy(lis1)
- 修改lis1中不可變類(lèi)型(如整型),lis2中對(duì)應(yīng)元素不改變
- 修改lis1中可變類(lèi)型(如列表),lis2中對(duì)應(yīng)元素改變
import copy
lis1=[1,2,[3,4],6,7,8]
lis2=copy.copy(lis1) #將lis1拷貝給lis2
lis1.append(9)
print(f'lis1:{lis1}') #lis1改變
print(f'lis2:{lis2}') #lis2不變
print('-'*50)
print(lis1[2])
lis1[2].append(5)
print(f'lis1:{lis1}') #lis1改變
print(f'lis2:{lis2}') #lis2也改變
# lis1[2]元素類(lèi)型是列表,是可變類(lèi)型,因此值改變,內(nèi)存地址沒(méi)有變。
# lis2[2]與lis1[1]指向了同一內(nèi)存地址,任意修改lis1[1] or lis2[1],另一元素都跟著改變。
lis1:[1, 2, [3, 4], 6, 7, 8, 9]
lis2:[1, 2, [3, 4], 6, 7, 8]
--------------------------------------------------
[3, 4]
lis1:[1, 2, [3, 4, 5], 6, 7, 8, 9]
lis2:[1, 2, [3, 4, 5], 6, 7, 8]
#在內(nèi)存當(dāng)中,列表存儲(chǔ)索引對(duì)應(yīng)變量值的地址
lis1[0]=0
#元素lis[0]是不可變類(lèi)型;修改值,內(nèi)存地址改變
print('列表lis1每個(gè)元素的內(nèi)存地址')
for i in range(len(lis1)):
print(id(lis1[i]))
print('-'*50)
print('列表lis2每個(gè)元素的內(nèi)存地址')
for i in range(len(lis2)):
print(id(lis2[i]))
#lis[0]為不可變類(lèi)型,值變,id改變。因此lis1[1]被修改了,lis2[1]內(nèi)存地址不變,因此未被修改。
列表lis1每個(gè)元素的內(nèi)存地址
140727203342744
140727203342808
2658013318784
140727203342936
140727203342968
140727203343000
140727203343032
--------------------------------------------------
列表lis2每個(gè)元素的內(nèi)存地址
140727203342776
140727203342808
2658013318784
140727203342936
140727203342968
140727203343000
4.7.2 深拷貝
import copy
lis1=[1,2,[3,4],6,7,8]
lis2=copy.deepcopy(lis1)
print('列表lis1每個(gè)元素的內(nèi)存地址')
for i in range(len(lis1)):
print(id(lis1[i]))
print('-'*50)
print('列表lis2每個(gè)元素的內(nèi)存地址')
for i in range(len(lis2)):
print(id(lis2[i]))
#兩個(gè)列表可變類(lèi)型元素內(nèi)存地址相同,不可變類(lèi)型元素內(nèi)存地址元素不同。
列表lis1每個(gè)元素的內(nèi)存地址
140727203342776
140727203342808
2658013591680
140727203342936
140727203342968
140727203343000
--------------------------------------------------
列表lis2每個(gè)元素的內(nèi)存地址
140727203342776
140727203342808
2657998541696
140727203342936
140727203342968
140727203343000
#不可變類(lèi)型元素內(nèi)存地址不同,所以深拷貝修改一個(gè)列表不會(huì)影響另一個(gè)列表
lis1=[1,2,[3,4],6,7,8]
lis2=copy.deepcopy(lis1)
lis1[0]=0
print(lis1)
print(lis2)
print('-'*50)
lis1[2].append(5)
print(lis1)
print(lis2)
[0, 2, [3, 4], 6, 7, 8]
[1, 2, [3, 4], 6, 7, 8]
--------------------------------------------------
[0, 2, [3, 4, 5], 6, 7, 8]
[1, 2, [3, 4], 6, 7, 8]
- 總結(jié):
- 拷貝:lis2=lis1,lis1內(nèi)部所有對(duì)象發(fā)生改變,lis2都跟著改變。
- 淺拷貝:lis2=copy.copy(lis1),lis1內(nèi)部不可變對(duì)象發(fā)生改變,lis2不變;lis1內(nèi)部可變對(duì)象發(fā)生改變,lis2改變。
- 深拷貝:lis2=copy.deepcopy(lis1),lis1內(nèi)部所有對(duì)象發(fā)生改變,lis2都不變。