Python3基礎之(三十)深拷貝和淺拷貝
阿新 • • 發佈:2018-11-19
首先請先看一下我之前寫的一篇文章 深拷貝與淺拷貝的區別
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
操作的結果是:a
和b
的地址是同一塊記憶體,改變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中的值改變而改變
>>>