1、深淺拷貝理解
- 深拷貝和淺拷貝需要注意的地方就是可變元素的拷貝:
- 在淺拷貝時,拷貝出來的新對象的地址和原對象是不一樣的,但是新對象里面的可變元素(如列表)的地址和原對象里的可變元素的地址是相同的,也就是說淺拷貝它拷貝的是淺層次的數據結構(不可變元素),對象里的可變元素作為深層次的數據結構並沒有被拷貝到新地址里面去,而是和原對象里的可變元素指向同一個地址,所以在新對象或原對象里對這個可變元素做修改時,兩個對象是同時改變的,但是深拷貝不會這樣,這個是淺拷貝相對於深拷貝最根本的區別。
- 也可以這樣理解:
- 深拷貝就是完全跟以前就沒有任何關系了,原來的對象怎么改都不會影響當前對象
- 淺拷貝,原對象的 list 元素改變的話會改變當前對象,如果當前對象中 list 元素改變了,也同樣會影響原對象。
- 淺拷貝就是藕斷絲連
- 深拷貝就是離婚了
2、深拷貝
- 克隆一份,修改拷貝后的對象中的可變元素不對原對象內容產生影響
- copy 模塊中的 deepcopy()
import copy list1 = [["北京多測師","成都多測師"],"上海多測師","深圳多測師","廣州多測師"] list2 = copy.deepcopy(list1) # 進行深拷貝 # 打印 list1 和 list2 兩個列表的內存地址 => 結果不一樣 print(id(list1)) # 3132367069640 print(id(list2)) # 3132368415752 # 打印 list1 和 list2 兩個列表中的子列表的內存地址 => 結果不一樣 print(id(list1[0])) # 3132368414728 print(id(list2[0])) # 3132368415688 # 修改拷貝后的 list2 中的可變數據類型的數據 list2[0][0] = "武漢多測師" # 結果 list2 列表修改了,但是不影響 list1 列表數據 print(list2) # [['武漢多測師', '成都多測師'], '上海多測師', '深圳多測師', '廣州多測師'] print(list1) # [['北京多測師', '成都多測師'], '上海多測師', '深圳多測師', '廣州多測師']
3、淺拷貝
- 修改拷貝后的內容中的可變數據,原對象內容隨之修改
- 列表函數 copy() 進行淺拷貝
list1 = [["北京多測師","成都多測師"],"上海多測師","深圳多測師","廣州多測師"] list2 = list1.copy() # 進行淺拷貝 # 打印 list1 和 list2 兩個列表的內存地址 => 結果不一樣 print(id(list1)) # 2105959073864 print(id(list2)) # 2105989035464 # 打印 list1 和 list2 兩個列表中的子列表的內存地址 => 結果一樣 print(id(list1[0])) # 2105989035592 print(id(list2[0])) # 2105989035592 # 修改拷貝后的 list2 中的可變數據類型的數據 list2[0][0] = "武漢多測師" # 結果 list2 列表修改了,list1 列表數據也修改了 print(list2) # [['武漢多測師', '成都多測師'], '上海多測師', '深圳多測師', '廣州多測師'] print(list1) # [['武漢多測師', '成都多測師'], '上海多測師', '深圳多測師', '廣州多測師']
- copy 模塊中的 copy()
import copy list1 = [["北京多測師","成都多測師"],"上海多測師","深圳多測師","廣州多測師"] list2 = copy.copy(list1) # 進行淺拷貝 # 打印 list1 和 list2 兩個列表的內存地址 => 結果不一樣 print(id(list1)) # 2129586840008 print(id(list2)) # 2129588186120 # 打印 list1 和 list2 兩個列表中的子列表的內存地址 => 結果一樣 print(id(list1[0])) # 2129588185096 print(id(list2[0])) # 2129588185096 # 修改拷貝后的 list2 中的可變數據類型的數據 list2[0][0] = "武漢多測師" # 結果 list2 列表修改了,list1 列表數據也修改了 print(list2) # [['武漢多測師', '成都多測師'], '上海多測師', '深圳多測師', '廣州多測師'] print(list1) # [['武漢多測師', '成都多測師'], '上海多測師', '深圳多測師', '廣州多測師']
4、實例講解
# 現有老公張三有額度為 200000 元的信用卡,卡號為:20200520,已使用的額度:15000 # 現需要實現張三的老婆 Andy 也需要綁定這張信用卡進行付款 zs_card = ["張三",20200520,[200000,15000]] # 張三名下的信用卡 ad_card = zs_card.copy() # 妻子 Andy 賬戶也開了一張綁定張三信用卡的信用卡,且修改姓名和卡號 ad_card[0] = "Andy" ad_card[1] = 20200521 print(ad_card) # 打印出 Andy 的信用卡信息 ['Andy', 20200521, [200000, 15000]] zs_card[2][1] += 2000 # 此時張三使用了信用卡且刷了 2000 元 print(ad_card) # 此時 Andy 的信用卡額度也隨之變化 # 運行結果如下 ['Andy', 20200521, [200000, 15000]] ['Andy', 20200521, [200000, 17000]] # 張三刷卡后,Andy 所持的信用卡已使用的額度隨之增長