python 深拷貝與淺拷貝

淺拷貝
淺拷貝是對一個對象的頂層拷貝,即可以理解爲:拷貝了引用,並沒有拷貝內容
例:

a = [1,2,3,4]
b=a
id(a)
2062999779784
id(b)
2062999779784

深拷貝
顧名思義,深層次的拷貝,深拷貝不僅僅拷貝引用,還會將整個拷貝內容複製到一片新的內存區域。

例:

import copy
c=copy.deepcopy(a)
id(c)
2062999779016
id(a)
2062999779784

會發現深拷貝會另外開闢儲存空間(id不同)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
當我們對a列表進行修改時:

a.append(5)
a
[1, 2, 3, 4, 5]
b
[1, 2, 3, 4, 5]
c
[1, 2, 3, 4]

此時,因爲b爲淺拷貝,與列表a指向同一片內存空間,所以一旦列表a改動,列表b也隨之改動
但列表c爲深拷貝,已經有自己獨立的內存區域,所以不會改動
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
【注】當我們利用深拷貝來拷貝一些列表的引用時,會進行依次拷貝(遞歸拷貝),即將引用的內容依次拷貝出來
例:

a = [1,2,3,4]
b = [9,8,7,6]
c = [a,b]
d = c
e = copy.deepcopy(c)
id(c)
2062999779144
id(d)
2062999779144
id(e)
2062999780296
#改變列表c中的列表a
a.append(5)
c
[[1, 2, 3, 4, 5], [9, 8, 7, 6]]
d
[[1, 2, 3, 4, 5], [9, 8, 7, 6]]
e
[[1, 2, 3, 4], [9, 8, 7, 6]]

淺拷貝的列表 d 會隨着列表c中子列表的更改而變化
深拷貝的列表 e 不會改變
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++我們再來看一種:
copy.copy
例:

#接上文程序繼續
f = copy.copy(c)
#對子列表a進行操作
a.insert(0,0)
c
[[0, 1, 2, 3, 4, 5], [9, 8, 7, 6]]
d
[[0, 1, 2, 3, 4, 5], [9, 8, 7, 6]]
f
[[0, 1, 2, 3, 4, 5], [9, 8, 7, 6]]
#接下來再看地址
id(c)
2062999779144
id(d)
2062999779144
id(f)
2062999779784
#對列表 c 進行操作
c.append(1)
c
[[0, 1, 2, 3, 4, 5], [9, 8, 7, 6], 1]
d
[[0, 1, 2, 3, 4, 5], [9, 8, 7, 6], 1]
f
[[0, 1, 2, 3, 4, 5], [9, 8, 7, 6]]

所以,我們會發現,當我們進行copy.copy操作時,會深拷貝當前列表,但是子列表仍然是淺拷貝。所以copy.copy只進行一層深拷貝。

我們剛剛進行的操作全都是在列表中進行的,下面我們換用元組來進行。
例:

 a = [1,2,3]
 b = [4,5,6]
 c = (a,b)
 d = copy.copy(c)
 id(c)
 2063002420488
 id(d)
 2063002420488
 a.append(4)
 c[0]
 [1, 2, 3, 4]
 d[0]
 [1, 2, 3, 4]

由程序可以發現,我們進行 copy.copy 功能的時候,當我們拷貝的是一個元組,則該操作與淺拷貝相同,這是因爲 copy.copy 會自動判斷數據是可變類型還是不可變類型,根據不同的數據類型進行不同的處理方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章