最近面試被問到python
中深拷貝和淺拷貝的知識
這里進(jìn)行下總結(jié),以便今后復(fù)習(xí)
python
中的深拷貝和淺拷貝和java
里面的概念是一樣的,所謂淺拷貝就是對引用的拷貝,所謂深拷貝就是對對象的資源的拷貝。
首先,對賦值操作我們要有以下認(rèn)識:
- 賦值是將一個對象的地址賦值給一個變量,讓變量指向該地址( 舊瓶裝舊酒 )。
- 修改不可變對象(
str
、tuple
)需要開辟新的空間 - 修改可變對象(
list
等)不需要開辟新的空間
- 淺拷貝僅僅復(fù)制了容器中元素的地址
>>> 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
地址都一樣,說明淺拷貝知識將容器內(nèi)的元素的地址復(fù)制了一份。這可以通過修改后,b
中字符串沒改變,但是list
元素隨著a
相應(yīng)改變得到驗證。
淺拷貝是在另一塊地址中創(chuàng)建一個新的變量或容器,但是容器內(nèi)的元素的地址均是源對象的元素的地址的拷貝。也就是說新的容器中指向了舊的元素( 新瓶裝舊酒 )。
- 深拷貝,完全拷貝了一個副本,容器內(nèi)部元素地址都不一樣
>>> 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
后,發(fā)現(xiàn)b
沒有發(fā)生任何改變,因為b
是一個完全的副本,元素地址與a
均不同,a
修改不影響b
。
深拷貝是在另一塊地址中創(chuàng)建一個新的變量或容器,同時容器內(nèi)的元素的地址也是新開辟的,僅僅是值相同而已,是完全的副本。也就是說( 新瓶裝新酒 )。