Python列表的深複製與淺複製

2021-10-19 08:54:25 字數 3096 閱讀 6024

首先看**:

l1 = [5, 4, 3, 2, 1]

# 用兩種方法實現對列表l1的拷貝

l2 = l1

l3 = l1[:]

print(l1) # [5, 4, 3, 2, 1]

print(l2) # [5, 4, 3, 2, 1]

print(l3) # [5, 4, 3, 2, 1]

#修改l1

l1[0] = 9

print(l1) # [9, 4, 3, 2, 1]

print(l2) # [9, 4, 3, 2, 1]

print(l3) # [5, 4, 3, 2, 1]

print(id(l1)) # 2927957162504

print(id(l2)) # 2927957162504

print(id(l3)) # 2927923243528

從結果來看,l1和l2位址是一樣的,也就是說l1和l2指向的是同一塊記憶體區域,顯然,通過 l2 = l1 操作,l1和l2都成了指向同一塊記憶體位址的「指標」,也就是說這個操作是為l1取了乙個別名,也可以說l2是l1的乙個引用。用一張圖來解釋:

那麼修改l1也就是在修改l2:

接下來看一下建立l3的過程,l3 = l1[:] ,這是將l1進行切片,並將切片後的列表拷貝到l3所指向的記憶體區域,同樣看圖:

也就是說l1和l3指向不同的記憶體區域,那麼修改l1並不會影響到l3:

通俗的來講,像l2這種,拷貝出來的物件和原物件的位址相同,為淺複製,像l3這種,分配新的記憶體空間並拷貝原始內容的,拷貝出來的物件和原物件的位址不同,為深複製

看乙個比較有意思的東西,看**:

l1 = [1,2,3,[1,3]]

l2 = l1[:]

l1[3][1] = 9

print(l1) # [1, 2, 3, [1, 9]]

print(l2) # [1, 2, 3, [1, 9]]

按照前面的理解,修改l1某個元素後,l2應該不會發生改變,可結果卻與我們預想的結果大相徑庭,於是,我們不得不思考一下l2深複製到底複製了什麼東西。實際上列表其實可以理解為乙個「指標」,l1[3]是乙個列表元素,l2[3]也是乙個列表元素,執行以下**:

print(id(l2[3])) # 2014816956232

print(id(l1[3])) # 2014816956232

我們發現l1[3]和l2[3]指向的位址是一樣的,也就是說在執行 l2 = l1[:] 的時候,將乙個位址拷貝了,所以修改l1[3]相當於修改l2[3],所以才會出現上述結果,這更加說明了列表其實就是乙個指向一片記憶體區域的「指標」。那麼我們是不是可以說列表l2深複製l1,但是對列表中每個元素進行複製時進行的是淺複製呢?答案顯而易見。

修改l1[3]中的元素:

列舉一下其他的拷貝列表的方式:

l4 = l1 * 1

print(id(l4)) # 2927957916296

l5 = list(l1)

print(id(l5)) # 2927957767816

import copy

l6 = copy.copy(l1)

print(id(l6)) # 2927956854024

l7 = copy.deepcopy(l1)

print(id(l7)) # 2927958503368

我們可以看到,這幾種拷貝方式所得到的的新物件與原物件的位址都不相同了,並沒有按照字面意思(copy進行淺複製,deepcopy進行深複製),那麼copy()和deepcopy()究竟有什麼區別呢,繼續看**:

list1 = [1,2,3,[1,3]]

list2 = list1[:]

list3 = copy.copy(list1)

list4 = copy.deepcopy(list1)

list1[3][0] = 9

print(list1) # [1, 2, 3, [9, 3]]

print(list2) # [1, 2, 3, [9, 3]]

print(list3) # [1, 2, 3, [9, 3]]

print(list4) # [1, 2, 3, [1, 3]]

print(id(list1[3])) # 2927923172616

print(id(list2[3])) # 2927923172616

print(id(list3[3])) # 2927923172616

print(id(list4[3])) # 2927967190728

可以發現copy()和前面提到的用 [:] 進行拷貝沒有本質上的區別,對列表中的每個元素進行複製時進行的是淺拷貝,而deepcopy()在複製列表中的每個元素的時候,進行的是深拷貝

python深複製與淺複製區別

1.copy.copy 淺拷貝 只拷貝父物件,不會拷貝物件的內部的子物件。2.copy.deepcopy 深拷貝 拷貝物件及其子物件 由於在python中物件之間賦值只是引用的傳遞,即多個物件指向同乙個位址,如 a 1,2,3 b a此時a與b是指向同乙個記憶體位址的,即儲存 1,2,3 的記憶體位...

python中深複製與淺複製

從定義上來說 1 copy.copy 是淺複製,只拷貝父物件,不會拷貝物件的內部的子物件。2 copy.deepcopy 是深複製,拷貝物件及其子物件。import copy a 1,2,3,4,a b 原始物件 b a 賦值,傳物件的引用 c copy.copy a 物件拷貝,淺拷貝 d copy...

淺複製與深複製

舉個複製 的例子 function clone p,s for var prop in p return s var a var b clone a,b b.hobby 1 reading b.hobby 1 reading c.hobby 1 reading 由上面的例子可以看出,當執行淺複製時,...