拷貝就是拷貝,何來深淺之說?
Python中,對象的賦值,拷貝(深/淺拷貝)之間是有差異的,如果使用的時候不注意,就可能產生意外的結果
其實這個是由於共享內存導致的結果
拷貝:原則上就是把數據分離出來,復制其數據,並以后修改互不影響。
先看 一個非拷貝的例子
=賦值:數據完全共享(=賦值是在內存中指向同一個對象,如果是可變(mutable)類型,比如列表,修改其中一個,另一個必定改變
如果是不可變類型(immutable),比如字符串,修改了其中一個,另一個並不會變
)
l1 = [1, 2, 3, ['aa', 'bb']] l2 = l1 l2[0]='aaa' l2[3][0]='bbb' print(l1) #['aaa', 2, 3, ['bbb', 'bb']] print(id(l1)==id(l2)) #True
l2 = l1 ,l1 完全賦值給l2 ,l2的內存地址與l1 相同,即內存完全指向
淺拷貝:數據半共享(復制其數據獨立內存存放,但是只拷貝成功第一層)
l1 = [1,2,3,[11,22,33]]
l2 = l1.copy()
print(l2) #[1,2,3,[11,22,33]]
l2[3][2]='aaa'
print(l1) #[1, 2, 3, [11, 22, 'aaa']]
print(l2) #[1, 2, 3, [11, 22, 'aaa']]
l1[0]= 0
print(l1) #[0, 2, 3, [11, 22, 'aaa']]
print(l2) #[1, 2, 3, [11, 22, 'aaa']]
print(id(l1)==id(l2)) #Flase
如上述代碼,l2淺拷貝了l1 ,之后l2把其列表中的列表的元素給修改,從結果看出,l1也被修改了。但是僅僅修改l1列表中的第一層元素,卻並沒有影響l2。
比較一下l2與l1的內存地址:False,說明,l2在內存中已經獨立出一部分復制了l1的數據,但是只是淺拷貝,第二層的數據並沒有拷貝成功,而是指向了l1中的第二層數據的內存地址,所以共享內存‘相當於‘’等號賦值’‘,所以就會有l2中第二層數據發生變化,l1中第二層數據也發生變化
如圖,這就是淺拷貝的原理,l2拷貝l1的時候只拷貝了他的第一層,也就是在其他內存中重新創建了l1的第一層數據,但是l2無法拷貝l1的第二層數據,也就是列表中的列表,所以他就只能指向l1中的第二層數據
由此,當修改l1中第二層數據的時候,淺拷貝l1的l2中的第二層數據也隨之發生改變
深拷貝:數據完全不共享(復制其數據完完全全放獨立的一個內存,完全拷貝,數據不共享)
深拷貝就是完完全全復制了一份,且數據不會互相影響,因為內存不共享。
深拷貝的方法有
導入模塊
import copy l1 = [1, 2, 3, [11, 22, 33]] # l2 = copy.copy(l1) 淺拷貝 l2 = copy.deepcopy(l1) print(l1,'>>>',l2) l2[3][0] = 1111 print(l1,">>>",l2)
由此可見深拷貝就是數據完完全全獨立拷貝出來一份。不會由原先數據變動而變動