Python中的深淺複製

2022-06-05 08:00:11 字數 2010 閱讀 5718

最近遇到了乙個問題,在python中對於物件的複製有兩種,copy()以及deepcopy(),為了研究他們之間的區別,寫下如下部落格。

首先檢視python的官方文件,得到如下解釋:

淺層複製和深層複製之間的區別僅與復合物件 (即包含其他物件的物件,如列表或類的例項) 相關:

乙個 淺層複製 會構造乙個新的復合物件,然後(在可能的範圍內)將原物件中找到的 引用 插入其中。

乙個 深層複製 會構造乙個新的復合物件,然後遞迴地將原始物件中所找到的物件的 副本 插入。

為了明白其中的原理,做了如下實驗:

簡單物件是指不包含子物件的物件,也就是只包含普通元素(數字,字串)的物件,對於簡單物件,copy與deepcopy方法沒有什麼區別,下面的一段**,可以先看一下效果是怎樣的。

import copy

if __name__ == '__main__':

a = [1, 2, 3, 4]

b = copy.copy(a)

c = copy.deepcopy(a)

print(a == b)

print(a is b)

print(a == c)

print(a is c)

執行上面的**,我們可以看到執行結果,深複製和淺複製的執行結果是一樣的

true # 說明 a 和 b 所指向的物件的內容相同

false # 說明 a 和 b 所指向的不是同乙個物件(位址不同)

true # 說明 a 和 c 所指向的物件的內容相同

false # 說明 a 和 c 所指向的不是同乙個物件(位址不同)

可以用一張圖來解釋一下,為什麼簡單物件的深淺複製是一樣的。

我們知道,上面的圖中,變數a指向乙個list物件(或者說是乙個list物件的引用),該物件在記憶體中占用乙個位址空間,當簡單物件執行copy和deepcopy中的物件時,我們可以看到無論時深複製還是淺複製,都是在記憶體中新開闢乙個位址空間,將原來物件中的內容複製過去,同時讓b成為新物件的引用。因此,我們看到a和b指向的物件是不一致的,但是內容是相同的。

複雜物件可以理解為另外包含其他簡單物件的物件,也就是包含子物件的物件,例如:list中巢狀list,或者dict中巢狀list等,對於複雜物件我們先來看乙個簡單的程式示例。

import copy

if __name__ == '__main__':

a =

b = copy.copy(a)

print(a is b)

print(a['address'] is b['address'])

c = copy.deepcopy(a)

print(a is c)

print(a['address'] is c['address'])

執行結果如下:

false  # 說明 a 和 b 不是同乙個物件的引用

true # 說明 a中的address 和 b 中的 address 是同乙個物件。黑人問號臉??

false # 說明 a 和 c 不是同乙個物件的引用

false # 說明 a中的address 和 c 中的 address 不是同乙個物件

下面我通過一張圖,來大概解釋一下為什麼會出現上面的結果。ps:具體物件的物件不一定是按照圖中的方式,為了能夠說明原理,本圖中將子物件的儲存空間單獨抽出,方便理解。

我們看到對於複雜物件(包含子物件的物件)的複製,深淺複製在實現原理上就有所不同了。通過上圖我們可以看到,複雜物件的深淺複製的區別在於複雜物件的子物件。可以看到:

python深淺複製 Python中的深淺拷貝

1.什麼是深淺拷貝?python中一切皆物件,python中的數字 字串 元組等,如果存放在了記憶體中,這部分記憶體裡面的內容是不會改變的,但是也有情況,記憶體中存放了可變物件,比如說列表和字典,他們的記憶體空間是可以被修改的。下面我們定義乙個列表 list 1,2,3,4,5 list1 list...

Python 深淺複製

python中的賦值語句不複製物件,它們在目標和物件之間建立繫結。對於可變的或包含可變項的容器,有時需要乙個副本,所以可以改變乙個副本而不改變另乙個。將建立乙個新物件,但它包含的是對原始物件包含的項的引用。a b list a c a.copy d copy.copy a 建立乙個新物件,並且遞迴的...

oc 深淺複製

淺 復 制 在複製操作時,對於被複製的物件的每一層複製都是指標複製。深 復 制 在複製操作時,對於被複製的物件至少有一層複製是物件複製。完全複製 在複製操作時,對於被複製的物件的每一層複製都是物件複製。注 1 在複製操作時,對於物件有n層是物件複製,我們可稱作n級深複製,此處n應大於等於1。2 對於...