新聞中心
python中深拷貝和淺拷貝的區(qū)別是什么,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
站在用戶的角度思考問題,與客戶深入溝通,找到啟東網(wǎng)站設計與啟東網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設計與互聯(lián)網(wǎng)技術結合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站設計、網(wǎng)站建設、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名注冊、網(wǎng)站空間、企業(yè)郵箱。業(yè)務覆蓋啟東地區(qū)。
先深拷貝和淺拷貝都是對象的拷貝,都會生成一個看起來相同的對象,他們本質(zhì)的區(qū)別是拷貝出來的對象的地址是否和原對象一樣,也就是地址的復制還是值的復制的區(qū)別。
什么是可變對象,什么是不可變對象:
可變對象是指,一個對象在不改變其所指向的地址的前提下,可以修改其所指向的地址中的值;
不可變對象是指,一個對象所指向的地址上值是不能修改的,如果你修改了這個對象的值,那么它指向的地址就改變了,相當于你把這個對象指向的值復制出來一份,然后做了修改后存到另一個地址上了,但是可變對象就不會做這樣的動作,而是直接在對象所指的地址上把值給改變了,而這個對象依然指向這個地址。
深拷貝和淺拷貝需要注意的地方就是可變元素的拷貝:
在淺拷貝時,拷貝出來的新對象的地址和原對象是不一樣的,但是新對象里面的可變元素(如列表)的地址和原對象里的可變元素的地址是相同的,也就是說淺拷貝它拷貝的是淺層次的數(shù)據(jù)結構(不可變元素),對象里的可變元素作為深層次的數(shù)據(jù)結構并沒有被拷貝到新地址里面去,而是和原對象里的可變元素指向同一個地址,所以在新對象或原對象里對這個可變元素做修改時,兩個對象是同時改變的,但是深拷貝不會這樣,這個是淺拷貝相對于深拷貝最根本的區(qū)別。
舉例說明:
#encoding=utf-8
import copy
a=[1,2,3,4,5,['a','b']]
#原始對象
b=a#賦值,傳對象的引用
c=copy.copy(a)#對象拷貝,淺拷貝
d=copy.deepcopy(a)#對象拷貝,深拷貝
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)#修改對象a
a[5].append('c')#修改對象a中的['a','b']數(shù)組對象
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])
結果:
從程序的結果來看,列表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元素改變的話會改變當前對象,如果當前對象中l(wèi)ist元素改變了,也同樣會影響原對象。
淺拷貝就是藕斷絲連
深拷貝就是離婚了
通常復制的時候要用深拷貝,因為淺拷貝后,兩個對象中不可變對象指向不同地址,相互不會改變,但是兩個對象中的可變元素是指向相同的地址,一個變了,另一個會同時改變,會有影響(list是可變對象)。
如果要讓原list和copy list沒有影響怎么辦?
用深拷貝,拷貝后完全開辟新的內(nèi)存地址來保存之前的對象,雖然可能地址執(zhí)行的內(nèi)容可能相同(同一個地址,例如’s’),但是不會相互影響。
比如:
List1=[‘a(chǎn)’,’b’,’c’]
List2=[‘a(chǎn)’,’b’,’c’]
兩個列表中的’a’的地址是相同的
Id(list1[0])=id(list2[0]),但是兩個列表的地址是不同的
通常來講不可變元素包含:
int,float,complex,long,str,unicode,tuple
看完上述內(nèi)容,你們掌握python中深拷貝和淺拷貝的區(qū)別是什么的方法了嗎?如果還想學到更多技能或想了解更多相關內(nèi)容,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
網(wǎng)頁標題:python中深拷貝和淺拷貝的區(qū)別是什么
當前路徑:http://fisionsoft.com.cn/article/ghhosd.html