python深拷貝和淺拷貝的區別

2021-10-07 03:24:36 字數 1610 閱讀 8638

首先深拷貝和淺拷貝都是物件的拷貝,都會生成乙個看起來相同的物件,他們本質的區別是拷貝出來的物件的位址是否和原物件一樣,也就是位址的複製還是值的複製的區別。

什麼是可變物件,什麼是不可變物件:

可變物件是指,乙個物件在不改變其所指向的位址的前提下,可以修改其所指向的位址中的值;

不可變物件是指,乙個物件所指向的位址上值是不能修改的,如果你修改了這個物件的值,那麼它指向的位址就改變了,相當於你把這個物件指向的值複製出來乙份,然後做了修改後存到另乙個位址上了,但是可變物件就不會做這樣的動作,而是直接在物件所指的位址上把值給改變了,而這個物件依然指向這個位址。

深拷貝和淺拷貝需要注意的地方就是可變元素的拷貝:

在淺拷貝時,拷貝出來的新物件的位址和原物件是不一樣的,但是新物件裡面的可變元素(如列表)的位址和原物件裡的可變元素的位址是相同的,也就是說淺拷貝它拷貝的是淺層次的資料結構(不可變元素),物件裡的可變元素作為深層次的資料結構並沒有被拷貝到新位址裡面去,而是和原物件裡的可變元素指向同乙個位址,所以在新物件或原物件裡對這個可變元素做修改時,兩個物件是同時改變的,但是深拷貝不會這樣,這個是淺拷貝相對於深拷貝最根本的區別。

舉例說明:

#encoding=utf-8

結果:

從程式的結果來看,列表a和b是賦值操作,兩個物件完全指向同乙個位址,a和b就是同一塊位址的兩個引用,其實就是乙個東西,所以乙個物件在修改淺層元素(不可變)或深層元素(可變)時,另乙個物件也同時在變;

c是a進行淺拷貝生成的物件,可以看到a(或b)和c兩個物件整體的id是不同的,但是裡面的第5個元素-列表的位址卻是相同的(指向同乙個位址),所以b在淺層次元素層面(不可變)增加乙個元素時,c並沒跟著增加,但是b的第5個元素-列表在增加乙個元素時,c的第5個元素也跟著增加了,這就是因為b和c的第5個元素-列表是指向同乙個位址的,這個位址上的值變了,在兩個地方會同時改變;

再看d,d的淺層次元素(不可變)和 深層次元素(可變)的位址和a,b,c都不一樣,所以,a,b,c無論怎麼修改,d都不會跟著改變,這就是深拷貝的結果。

也可以這樣理解:

深拷貝就是完全跟以前就沒有任何關係了,原來的物件怎麼改都不會影響當前物件

淺拷貝,原物件的list元素改變的話會改變當前物件,如果當前物件中list元素改變了,也同樣會影響原物件。

淺拷貝就是藕斷絲連

深拷貝就是離婚了

通常複製的時候要用深拷貝,因為淺拷貝後,兩個物件中不可變物件指向不同位址,相互不會改變,但是兩個物件中的可變元素是指向相同的位址,乙個變了,另乙個會同時改變,會有影響(list是可變物件)。

如果要讓原list和copy list沒有影響怎麼辦?

用深拷貝,拷貝後完全開闢新的記憶體位址來儲存之前的物件,雖然可能位址執行的內容可能相同(同乙個位址,例如』s』),但是不會相互影響。

比如:list1=[『a』,』b』,』c』]

list2=[『a』,』b』,』c』]

兩個列表中的』a』的位址是相同的

id(list1[0])=id(list2[0]),但是兩個列表的位址是不同的

通常來講不可變元素包含:

int,float,complex,long,str,unicode,tuple

python 深拷貝 Python深拷貝和淺拷貝!

在python中,物件賦值實際上是物件的引用。當建立乙個物件,然後把它賦給另乙個變數的時候,python並沒有拷貝這個物件,而只是拷貝了這個物件的引用 一般有三種方法,alist 1,2,3,a b 1 直接賦值 b alist,預設淺拷貝傳遞物件的引用而已,原始列表改變,被賦值的b也會做相同的改變...

Python 深拷貝和淺拷貝

淺拷貝只拷貝了引用,並沒有拷貝內容,相當於把原來的引用複製了乙份給新的變數 深拷貝是將原來的值複製了乙份到新的地方 in 30 a 1,2,3 in 31 b a in 32 id a out 32 140618626865352 in 33 id b out 33 140618626865352 ...

python深拷貝和淺拷貝

copy.copy 淺拷貝 只拷貝父物件,不會拷貝物件的內部的子物件。比深拷貝更加節省記憶體 copy.deepcopy 深拷貝 拷貝物件及其子物件 用乙個簡單的例子說明如下 import copy公升 a 1,2,3,4,a b c b a c copy.copy a d copy.deepcop...