1. 程式人生 > >關於Python深淺拷貝

關於Python深淺拷貝

拷貝:

  說明原則上就是把資料分離出來,複製其資料,並以後修改互不影響。

何來深淺拷貝的說法?

  深淺拷貝的“深”和“淺”可以理解為從變數到硬碟上的物理儲存介質之間的層次的多少。

 

下面用一個示例來解釋淺拷貝:

 1 #Author : Kelvin
 2 #Date : 2019/1/5 0:41
 3 import copy
 4 #淺拷貝的第一種方式(使用物件自身的copy方法)
 5 li1=[["bob","alvin"],"kelvin","alex"]
 6 li2=li1.copy() #呼叫列表自身方法拷貝
 7 li2[1]="kelvin-sb
" #修改li2的第二個元素 8 print("li1: ",li1) 9 print("li2: ",li2) 10 #執行結果(只有li2改變了): 11 #li1: [['bob', 'alvin'], 'kelvin', 'alex'] 12 # li2: [['bob', 'alvin'], 'kelvin-sb', 'alex'] 13 print("-------"*6) 14 li2[0][0]="bob-sb" #修改li2的第一個元素中的第一個元素 15 print("li1: ",li1) 16 print("li2: ",li2) 17 #執行結果(li1和li2都改變了):
18 # li1: [['bob-sb', 'alvin'], 'kelvin', 'alex'] 19 # li2: [['bob-sb', 'alvin'], 'kelvin-sb', 'alex'] 20 21 22 23 24 25 #淺拷貝的第二種方式(使用copy模組的copy方法) 26 li1=[["bob","alvin"],"kelvin","alex"] 27 li2=copy.copy(li1) #呼叫copy模組方法拷貝 28 li2[1]="kelvin-sb" #修改li2的第二個元素 29 print("li1: ",li1) 30 print("
li2: ",li2) 31 #執行結果(只有li2改變了): 32 #li1: [['bob', 'alvin'], 'kelvin', 'alex'] 33 # li2: [['bob', 'alvin'], 'kelvin-sb', 'alex'] 34 print("-------"*6) 35 li2[0][0]="bob-sb" #修改li2的第一個元素中的第一個元素 36 print("li1: ",li1) 37 print("li2: ",li2) 38 #執行結果(li1和li2都改變了): 39 # li1: [['bob-sb', 'alvin'], 'kelvin', 'alex'] 40 # li2: [['bob-sb', 'alvin'], 'kelvin-sb', 'alex']

對於上面淺拷貝的示例我們可以看到,當淺拷貝之後,修改其中一個不可變型別元素(數字,字串等),拷貝前後物件之間互不干擾,沒有影響,但是當修改了可變型別元素(列表,字典等),拷貝前後物件均發生改變。其中的原因就是因為不可變型別直接儲存在物理硬碟上,而可變型別則會包含多個不可變型別而形成一個獨立的記憶體地址,也就是多了一“層”。下面用圖示具體說明:

  只改變“kelvin”圖示:

  改變li1第一個元素(列表)中的值圖示:

**注:認真理清圖示表達的含義,理解好深淺的內涵。

 

  

  下面再通過一個示例來了解深拷貝:

 1 import copy
 2 #深拷貝只能呼叫copy模組的deepcopy方法
 3 li1=[["bob","alvin"],"kelvin","alex"]
 4 li2=copy.deepcopy(li1) #呼叫copy模組方法拷貝
 5 li2[1]="kelvin-sb"  #修改li2的第二個元素
 6 print("li1: ",li1)
 7 print("li2: ",li2)
 8 #執行結果(只有li2改變了):
 9 #li1:  [['bob', 'alvin'], 'kelvin', 'alex']
10 # li2:  [['bob', 'alvin'], 'kelvin-sb', 'alex']
11 print("-------"*6)
12 li2[0][0]="bob-sb"  #修改li2的第一個元素中的第一個元素
13 print("li1: ",li1)
14 print("li2: ",li2)
15 #執行結果(只有li2改變了):
16 # li1:  [['bob', 'alvin'], 'kelvin', 'alex']
17 # li2:  [['bob-sb', 'alvin'], 'kelvin-sb', 'alex']

  深拷貝相比較淺拷貝就容易理解的多,因為深拷貝就是完完全全的拷貝,拷貝前後的兩個物件佔有獨立的記憶體空間,不存在共享空間,因此拷貝前後物件相互改變無影響。

 

 

 

最後來一個深淺拷貝的應用例項(隨意例項):

 1 #Author : Kelvin
 2 #Date : 2019/1/5 1:37
 3 
 4 import copy
 5 kelvin=["kelvin",123,[10000,]] #戶主  卡號  餘額
 6 wife=kelvin.copy()  #給媳婦共享銀行卡
 7 wife[1]=234 #設定媳婦卡號
 8 wife[0]="peiqi" #媳婦銀行卡戶主
 9 wife[2][0]-=2000 #媳婦消費2000元
10 print(kelvin)
11 print(wife)
12 print("------"*6)
13 # 輸出結果(實現共享賬戶):
14 # ['kelvin', 123, [8000]]
15 # ['peiqi', 234, [8000]]
16 
17 
18 #小三賬戶不能淺拷貝,因為媳婦會發現賬戶少錢
19 xiaosan=copy.deepcopy(kelvin)
20 xiaosan[0]="sanzi" #小三銀行卡戶主
21 xiaosan[1]=666 #設定小三卡號
22 xiaosan[2][0]-=3000 #小三消費3000元
23 print(kelvin)
24 print(xiaosan)
25 # 輸出結果(老婆不會發現):
26 # ['kelvin', 123, [10000]]
27 # ['sanzi', 666, [7000]]