Python 深拷貝與淺拷貝

2022-09-17 15:18:11 字數 4159 閱讀 3518

分享到:29

python中,物件的賦值,拷貝(深/淺拷貝)之間是有差異的,如果使用的時候不注意,就可能產生意外的結果。

下面本文就通過簡單的例子介紹一下這些概念之間的差別。

物件賦值

直接看一段**:

python12

3456

78910

1112

1314

1516

17will=[

"will",28

,["python"

,"c#"

,"j**ascript"]]

wilber

=will

printid(

will

)print

will

print[id

(ele

)for

ele

inwill

]printid(

wilber

)print

wilber

print[id

(ele

)for

ele

inwilber

]will[0

]="wilber"

will[2

].("css"

)printid(

will

)print

will

print[id

(ele

)for

ele

inwill

]printid(

wilber

)print

wilber

print[id

(ele

)for

ele

inwilber

]**的輸出為:

下面來分析一下這段**:

可以理解為,python中,物件的賦值都是進行物件引用(記憶體位址)傳遞

這裡需要注意的一點是,str是不可變型別,所以當修改的時候會替換舊的物件,產生乙個新的位址39758496

淺拷貝

下面就來看看淺拷貝的結果:

python12

3456

78910

1112

1314

1516

1718

1920

import

copy

will=[

"will",28

,["python"

,"c#"

,"j**ascript"]]

wilber

=copy

.copy

(will

)printid(

will

)print

will

print[id

(ele

)for

ele

inwill

]printid(

wilber

)print

wilber

print[id

(ele

)for

ele

inwilber

]will[0

]="wilber"

will[2

].("css"

)printid(

will

)print

will

print[id

(ele

)for

ele

inwill

]printid(

wilber

)print

wilber

print[id

(ele

)for

ele

inwilber

]**結果為:

分析一下這段**:

淺拷貝會建立乙個新的物件,這個例子中」wilber is not will」

但是,對於物件中的元素,淺拷貝就只會使用原始元素的引用(記憶體位址),也就是說」wilber[i] is will[i]」

由於list的第乙個元素是不可變型別,所以will對應的list的第乙個元素會使用乙個新的物件39758496

但是list的第三個元素是乙個可不型別,修改操作不會產生新的物件,所以will的修改結果會相應的反應到wilber上

總結一下,當我們使用下面的操作的時候,會產生淺拷貝的效果:

深拷貝

最後來看看深拷貝:

python12

3456

78910

1112

1314

1516

1718

1920

import

copy

will=[

"will",28

,["python"

,"c#"

,"j**ascript"]]

wilber

=copy

.deepcopy

(will

)printid(

will

)print

will

print[id

(ele

)for

ele

inwill

]printid(

wilber

)print

wilber

print[id

(ele

)for

ele

inwilber

]will[0

]="wilber"

will[2

].("css"

)printid(

will

)print

will

print[id

(ele

)for

ele

inwill

]printid(

wilber

)print

wilber

print[id

(ele

)for

ele

inwilber

]**的結果為:

分析一下這段**:

跟淺拷貝類似,深拷貝也會建立乙個新的物件,這個例子中」wilber is not will」

但是,對於物件中的元素,深拷貝都會重新生成乙份(有特殊情況,下面會說明),而不是簡單的使用原始元素的引用(記憶體位址)

例子中will的第三個元素指向39737304,而wilber的第三個元素是乙個全新的物件39773088,也就是說,」wilber[2] is not will[2]」

由於list的第乙個元素是不可變型別,所以will對應的list的第乙個元素會使用乙個新的物件39758496

但是list的第三個元素是乙個可不型別,修改操作不會產生新的物件,但是由於」wilber[2] is not will[2]」,所以will的修改不會影響wilber

拷貝的特殊情況

其實,對於拷貝有一些特殊情況:

也就是說,對於這些型別,」obj is copy.copy(obj)」 、」obj is copy.deepcopy(obj)」

總結

Python 淺拷貝與深拷貝

淺拷貝 構造方法或切片 做的是淺拷貝 即拷貝了最外層容器,副本中的元素是原容器中元素的引用 在 python 中,通過乙個物件向另外乙個物件賦值,實際僅僅是賦值了物件的引用,而非建立乙個物件並賦值。那如何真正拷貝物件呢?我們看一下兩種不同的拷貝方式。先從乙個示例看起 anndy anndy age ...

Python 淺拷貝與深拷貝

以下例項是使用 copy 模組的 copy.copy 淺拷貝 和 copy.deepcopy usr bin python coding utf 8 import copy a 1,2,3,4,a b 原始物件 b a 賦值,傳物件的引用 c copy.copy a 物件拷貝,淺拷貝 d copy....

python 深拷貝與淺拷貝

當乙個變數 的時候,約定為 指向位址的過程 如果copy.copy 拷貝的是元組,那麼它不會進行淺拷貝,僅僅是指向 因為元組是不可變資料型別,那麼意味著資料一定不能修改,因此用copy.copy的 時候它會自動判斷,是指向。如果,用copy.copy copy.deepcopy 對乙個全部是不可變型...