轉載自:會發光的二極管
最近面試被問到python中深拷貝和淺拷貝的知識
這裡進行下總結,以便今後複習
python中的深拷貝和淺拷貝和java裡面的概念是一樣的,所謂淺拷貝就是對引用的拷貝,所謂深拷貝就是對對象的資源的拷貝。
首先,對指派操作我們要有以下認識:指派是将一個對象的位址指派給一個變量,讓變量指向該位址( 舊瓶裝舊酒 )。
修改不可變對象(str、tuple)需要開辟新的空間
修改可變對象(list等)不需要開辟新的空間淺拷貝僅僅複制了容器中元素的位址
>>> a=['hello',[1,2,3]]
>>> b=a[:]
>>> [id(x) for x in a]
[55792504, 6444104]
>>> [id(x) for x in b]
[55792504, 6444104]
>>> a[0]='world'
>>> a[1].append(4)
>>> print(a)
['world', [1, 2, 3, 4]]
>>> print(b)
['hello', [1, 2, 3, 4]]
這裡可以看出,未修改前,a和b中元素的位址都是相同的,不可變的hello
和可變的list位址都一樣,說明淺拷貝知識将容器内的元素的位址複制了一份。這可以通過修改後,b中字元串沒改變,但是list元素随着a相應改變得到驗證。淺拷貝是在另一塊位址中建立一個新的變量或容器,但是容器内的元素的位址均是源對象的元素的位址的拷貝。也就是說新的容器中指向了舊的元素( 新瓶裝舊酒 )。深拷貝,完全拷貝了一個副本,容器内部元素位址都不一樣
>>> from copy import deepcopy
>>> a=['hello',[1,2,3]]
>>> b=deepcopy(a)
>>> [id(x) for x in a]
[55792504, 55645000]
>>> [id(x) for x in b]
[55792504, 58338824]
>>> a[0]='world'
>>> a[1].append(4)
>>>
>>> print(a)
['world', [1, 2, 3, 4]]
>>> print(b)
['hello', [1, 2, 3]]
這裡可以看出,深拷貝後,a和b的位址以及a和b中的元素位址均不同,這是完全拷貝的一個副本,修改a後,發現b沒有發生任何改變,因為b是一個完全的副本,元素位址與a均不同,a修改不影響b。深拷貝是在另一塊位址中建立一個新的變量或容器,同時容器内的元素的位址也是新開辟的,僅僅是值相同而已,是完全的副本。也就是說( 新瓶裝新酒 )。