1. 程式人生 > >Python3基礎之(三十)深拷貝和淺拷貝

Python3基礎之(三十)深拷貝和淺拷貝

首先請先看一下我之前寫的一篇文章 深拷貝與淺拷貝的區別
Python中,物件的賦值,拷貝(深/淺拷貝)之間是有差異的,如果使用的時候不注意,就可能產生意外的結果。

一、id

深拷貝和淺拷貝最大的區別就在於佔用記憶體的不同,所以首先要知道怎麼檢視物件的地址。一個物件的id值在CPython直譯器裡就代表它在記憶體中的 地址

>>> import copy
>>> a=[1,2,3]
>>> b=a
>>> id(a)
2090106460936
>>> id(b)
2090106460936
>>
> id(a)==id(b) True >>> b[0]=22222 >>> print(a,b) [22222, 2, 3] [22222, 2, 3]

上例中可以看出b=a操作的結果是:ab的地址是同一塊記憶體,改變b的值,a的值也會跟著改變。實際上a和b都是記憶體地址為:2090106460936的記憶體一個引用(也就是c語言中常說的指標)

二、淺拷貝copy.copy

當使用淺拷貝時,python只是拷貝了最外圍的物件本身(物件本身的地址變了),內部的元素都只是拷貝了一個引用而已(內部元素的地址沒有改變)。看程式碼:

>>
> import copy >>> a=[1,2,3] >>> c=copy.copy(a) #拷貝了a的外圍物件本身, >>> id(c) 4383658568 >>> print(id(a)==id(c)) #id 改變 為false False >>> c[1]=22222 #此時,我去改變c的第二個值時,a不會被改變。 >>> print(a,c) [1, 2, 3] [1, 22222, 3] #a值不變,c的第二個值變了,這就是copy和‘==’的不同

三、深拷貝copy.deepcopy

deepcopy對外圍內部元素都進行了拷貝物件本身,而不是拷貝物件的引用。可以理解為深拷貝就是完全拷貝,淺拷貝就是不完全拷貝。

#copy.copy()

>>> a=[1,2,[3,4]]  #第三個值為列表[3,4],即內部元素
>>> d=copy.copy(a) #淺拷貝只是拷貝a中的1,2,[3,4]這些內部元素的引用,而非內部元素物件的本身
>>> id(a)==id(d)#只是拷貝了物件本身,而非內部元素物件本身
False
>>> id(a[2])==id(d[2])#內部元素只是拷貝了引用
True
>>> id(a[1])==id(d[1])
True
>>> a[2][0]=3333  #改變a中內部原屬列表中的第一個值
>>> d             #這時d中的列表元素也會被改變
[1, 2, [3333, 4]]


#copy.deepcopy()

>>> e=copy.deepcopy(a) #e為深拷貝了a
>>> a[2][0]=333 #改變a中內部元素列表第一個的值
>>> e
[1, 2, [3333, 4]] #因為時深拷貝,這時e中內部元素[]列表的值不會因為a中的值改變而改變
>>>