關於Python深淺拷貝
阿新 • • 發佈:2019-01-05
拷貝:
說明:原則上就是把資料分離出來,複製其資料,並以後修改互不影響。
何來深淺拷貝的說法?
深淺拷貝的“深”和“淺”可以理解為從變數到硬碟上的物理儲存介質之間的層次的多少。
下面用一個示例來解釋淺拷貝:
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]]