您好,登錄后才能下訂單哦!
python中深拷貝和淺拷貝的區(qū)別是什么,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
什么是可變對(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é)果:
從程序的結(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è)資訊頻道,感謝各位的閱讀!
免責(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)容。