溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

python中深拷貝和淺拷貝的區(qū)別是什么

發(fā)布時(shí)間:2021-07-05 16:12:07 來(lái)源:億速云 閱讀:261 作者:Leah 欄目:大數(shù)據(jù)

python中深拷貝和淺拷貝的區(qū)別是什么,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

先深拷貝和淺拷貝都是對(duì)象的拷貝,都會(huì)生成一個(gè)看起來(lái)相同的對(duì)象,他們本質(zhì)的區(qū)別是拷貝出來(lái)的對(duì)象的地址是否和原對(duì)象一樣,也就是地址的復(fù)制還是值的復(fù)制的區(qū)別。

什么是可變對(duì)象,什么是不可變對(duì)象:

可變對(duì)象是指,一個(gè)對(duì)象在不改變其所指向的地址的前提下,可以修改其所指向的地址中的值;

不可變對(duì)象是指,一個(gè)對(duì)象所指向的地址上值是不能修改的,如果你修改了這個(gè)對(duì)象的值,那么它指向的地址就改變了,相當(dāng)于你把這個(gè)對(duì)象指向的值復(fù)制出來(lái)一份,然后做了修改后存到另一個(gè)地址上了,但是可變對(duì)象就不會(huì)做這樣的動(dòng)作,而是直接在對(duì)象所指的地址上把值給改變了,而這個(gè)對(duì)象依然指向這個(gè)地址。

深拷貝和淺拷貝需要注意的地方就是可變?cè)氐目截悾?/strong>

在淺拷貝時(shí),拷貝出來(lái)的新對(duì)象的地址和原對(duì)象是不一樣的,但是新對(duì)象里面的可變?cè)兀ㄈ缌斜恚┑牡刂泛驮瓕?duì)象里的可變?cè)氐牡刂肥窍嗤?,也就是說(shuō)淺拷貝它拷貝的是淺層次的數(shù)據(jù)結(jié)構(gòu)(不可變?cè)兀?,?duì)象里的可變?cè)刈鳛樯顚哟蔚臄?shù)據(jù)結(jié)構(gòu)并沒(méi)有被拷貝到新地址里面去,而是和原對(duì)象里的可變?cè)刂赶蛲粋€(gè)地址,所以在新對(duì)象或原對(duì)象里對(duì)這個(gè)可變?cè)刈鲂薷臅r(shí),兩個(gè)對(duì)象是同時(shí)改變的,但是深拷貝不會(huì)這樣,這個(gè)是淺拷貝相對(duì)于深拷貝最根本的區(qū)別。

舉例說(shuō)明:

#encoding=utf-8

import copy
a=[1,2,3,4,5,['a','b']]
#原始對(duì)象
b=a#賦值,傳對(duì)象的引用
c=copy.copy(a)#對(duì)象拷貝,淺拷貝
d=copy.deepcopy(a)#對(duì)象拷貝,深拷貝
print "a=",a,"    id(a)=",id(a),"id(a[5])=",id(a[5])
print "b=",b,"    id(b)=",id(b),"id(b[5])=",id(b[5])
print "c=",c,"    id(c)=",id(c),"id(c[5])=",id(c[5])
print "d=",d,"    id(d)=",id(d),"id(d[5])=",id(d[5])
print "*"*70

a.append(6)#修改對(duì)象a
a[5].append('c')#修改對(duì)象a中的['a','b']數(shù)組對(duì)象
print "a=",a,"    id(a)=",id(a),"id(a[5])=",id(a[5])
print "b=",b,"    id(b)=",id(b),"id(b[5])=",id(b[5])
print "c=",c,"       id(c)=",id(c),"id(c[5])=",id(c[5])
print "d=",d,"            id(d)=",id(d),"id(d[5])=",id(d[5])

結(jié)果:
 

python中深拷貝和淺拷貝的區(qū)別是什么

從程序的結(jié)果來(lái)看,列表a和b是賦值操作,兩個(gè)對(duì)象完全指向同一個(gè)地址,a和b就是同一塊地址的兩個(gè)引用,其實(shí)就是一個(gè)東西,所以一個(gè)對(duì)象在修改淺層元素(不可變)或深層元素(可變)時(shí),另一個(gè)對(duì)象也同時(shí)在變;

c是a進(jìn)行淺拷貝生成的對(duì)象,可以看到a(或b)和c兩個(gè)對(duì)象整體的id是不同的,但是里面的第5個(gè)元素-列表的地址卻是相同的(指向同一個(gè)地址),所以b在淺層次元素層面(不可變)增加一個(gè)元素時(shí),c并沒(méi)跟著增加,但是b的第5個(gè)元素-列表在增加一個(gè)元素時(shí),c的第5個(gè)元素也跟著增加了,這就是因?yàn)閎和c的第5個(gè)元素-列表是指向同一個(gè)地址的,這個(gè)地址上的值變了,在兩個(gè)地方會(huì)同時(shí)改變;

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

也可以這樣理解:

深拷貝就是完全跟以前就沒(méi)有任何關(guān)系了,原來(lái)的對(duì)象怎么改都不會(huì)影響當(dāng)前對(duì)象

淺拷貝,原對(duì)象的list元素改變的話會(huì)改變當(dāng)前對(duì)象,如果當(dāng)前對(duì)象中l(wèi)ist元素改變了,也同樣會(huì)影響原對(duì)象。

淺拷貝就是藕斷絲連

深拷貝就是離婚了

通常復(fù)制的時(shí)候要用深拷貝,因?yàn)闇\拷貝后,兩個(gè)對(duì)象中不可變對(duì)象指向不同地址,相互不會(huì)改變,但是兩個(gè)對(duì)象中的可變?cè)厥侵赶蛳嗤牡刂罚粋€(gè)變了,另一個(gè)會(huì)同時(shí)改變,會(huì)有影響(list是可變對(duì)象)。

如果要讓原list和copy list沒(méi)有影響怎么辦?

用深拷貝,拷貝后完全開(kāi)辟新的內(nèi)存地址來(lái)保存之前的對(duì)象,雖然可能地址執(zhí)行的內(nèi)容可能相同(同一個(gè)地址,例如’s’),但是不會(huì)相互影響。

比如:

List1=[‘a(chǎn)’,’b’,’c’]

List2=[‘a(chǎn)’,’b’,’c’]

兩個(gè)列表中的’a’的地址是相同的

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

通常來(lái)講不可變?cè)匕?/strong>

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

看完上述內(nèi)容,你們掌握python中深拷貝和淺拷貝的區(qū)別是什么的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI