python進階----深拷貝&淺拷貝

複製須要區分,,複製的是源文件的數據,仍是指向源文件數據的地址python

1.引用   b=a時,理解爲b指向了a指向的數據,至關於引用複製app

a=[1,2]
b=a
#驗證複製的是數據仍是地址
#1.查看ab的地址
id(a)  #2677646858824
id(b) #2677646858824
#2. a增長1個元素,查看b是否增長
a.append(3)
a #[1,2,3]
b #[1,2,3]

 2. 淺拷貝--copy.copy()函數

import copy
a=[1,2]
b=[3,4]
c=[a,b]
d=copy.copy(c)

#驗證問題1:d是否執行c地址
#驗證方法1
id(d) #2677647114120
id(c) #2677644514824
#驗證方法2
c.append(6)
c  #[[1, 2], [3, 4], 6]
d  #[[1, 2], [3, 4]]
結論:d沒有指向c的地址

驗證問題2:d執行a,b的地址,仍是隻是複製了a,b的值
#驗證方法1
id(d[0]) #2677647113672
id(c[0]) #2677647113672
#驗證方法2
a.append(5)
c  #[[1, 2, 5], [3, 4]]
d  #[[1, 2, 5], [3, 4]]
結論:,d中的a與c中的a,地址相同,說明d中的a,與c中的a均指向a的地址的

  淺拷貝僅僅把最外面1層進行了copy,並無把裏面多層嵌套進行遞歸拷貝,裏面的仍是指向原來的地址spa

3.深拷貝 copy.deepcopy()code

import copy
a=[1,2]
b=[3,4]
c=[a,b]
d=copy.deepcopy(c)

#驗證問題1:d是否執行c地址
#驗證方法1
id(d) #2677647114120
id(c) #2677644514824
#驗證方法2
c.append(6)
c  #[[1, 2], [3, 4], 6]
d  #[[1, 2], [3, 4]]
結論:d沒有指向c的地址

驗證問題2:d執行a,b的地址,仍是隻是複製了a,b的值
#驗證方法1
id(c[0]) #2677647113672
id(d[0]) #2677645539912
#驗證方法2
a.append(5)
c  #[[1, 2, 5], [3, 4]]
d  #[[1, 2], [3, 4]]
結論:,d中的a與c中的a,地址不一樣,說明d中的a是複製了a的值,並無指向a的地址

  深拷貝遞歸拷貝, 多層時,每層都拷貝對象的值對象

4.深拷貝和淺拷貝的應用  blog

a=[1,2]
def aa(num):
    num.append(3)
    
a #[1, 2]
aa(a)
a #[1, 2, 3]

#結論:函數傳遞的實參,必定傳遞的是引用地址,因此函數會改變原數據

#若是想不改變源數據須要複製,最好用深複製
aa(copy.deepcopy(a))
a  #[1, 2]

5.注意事項遞歸

a=(1,2)
b=[1,2]
a1=copy.copy(a)
b1=copy.copy(b)
id(a)   #2677645526152
id(a1)  #2677645526152
id(b)    #2677645754888
id(b1)   #2677647113800
#結論:元組即便是1層,copy不拷貝,至關實用"="

#驗證:元組中嵌套列表是都拷貝
a=[1,2]
b=(3,4,a)
b1=copy.copy(b)
id(b)   #2677645507248
id(b1) #2677645507248
#結論是不拷貝

列表是可變的,,因此能夠copy,元祖是不可變的,copy後改變不了,因此copy先後的2個set均不能被修改,但佔用了2個空間,,沒有意義可是浪費空間,因此不能copyclass

a=(1,2)
a1=copy.deepcopy(a)
id(a)   #2677645531976
id(a1) #2677645531976

a=[1,2]
b=(3,4,a)
b1=copy.deepcopy(b)
id(b)   #2677645547848
id(b1) #2677645507896

 結論:若是copy的是對象多層嵌套中的對象都不可變,則深拷貝和淺拷貝都失效,僅僅指向引用,若是最外層不可變,內層嵌套中包含可變對象,淺拷貝不拷貝,指向引用,深拷貝進行copy import

 

總結論:

淺拷貝

若是最外層是list可變的,淺拷貝只拷貝最外層,內部的指向引用,若是最外層是set不可變的,不論裏面嵌套的可不可變,淺拷貝都不進行copy,只是指向引用

深拷貝

若是最外層是list可變的,深拷貝遞歸拷貝,若是最外層是set不可變的,裏面嵌套的包含可變的,深拷貝進行copy,若是裏面嵌套的也無可變的,深copy也不copy

相關文章
相關標籤/搜索