Python深拷貝與淺拷貝用法實(shí)例分析
本文實(shí)例講述了Python深拷貝與淺拷貝用法。分享給大家供大家參考,具體如下:
1、對(duì)象的賦值
對(duì)象的賦值實(shí)際上是對(duì)象之間的引用:當(dāng)創(chuàng)建一個(gè)對(duì)象,然后將這個(gè)對(duì)象賦值給另外一個(gè)變量的時(shí)候,python并沒(méi)有拷貝這個(gè)對(duì)象,而只是拷貝了這個(gè)對(duì)象的引用。
當(dāng)對(duì)對(duì)象做賦值或者是參數(shù)傳遞或者作為返回值的時(shí)候,總是傳遞原始對(duì)象的引用,而不是一個(gè)副本。如下所示:
在python中將一個(gè)變量賦值給另一個(gè)變量,傳遞的是引用.無(wú)論是a的內(nèi)層變化還是外層變化,b都會(huì)發(fā)生同樣的變化.因?yàn)椋夂停嶂赶蛄送粋€(gè)引用.類似于c語(yǔ)言中的同一片內(nèi)存地址.
#coding=utf-8 a = [1,2,3,['a','b','c']] b = a print('*'*50) print('--- b = a ---') print('a = %s'%a) print('b = %s'%b) a.append(4) print('--- 外層a增加了元素4 ---') print('a = %s'%a) print('b = %s'%b) print('--- 內(nèi)層增加了元素"d" ---') a[3].append('d') print('a = %s'%a) print('b = %s'%b)
運(yùn)行結(jié)果:
**************************************************
--- b = a ---
a = [1, 2, 3, ['a', 'b', 'c']]
b = [1, 2, 3, ['a', 'b', 'c']]
--- 外層a增加了元素4 ---
a = [1, 2, 3, ['a', 'b', 'c'], 4]
b = [1, 2, 3, ['a', 'b', 'c'], 4]
--- 內(nèi)層增加了元素'd' ---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
b = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
2、對(duì)象的復(fù)制
當(dāng)你想修改一個(gè)對(duì)象,而且讓原始的對(duì)象不受影響的時(shí)候,那么就需要使用到對(duì)象的復(fù)制,對(duì)象的復(fù)制可以通過(guò)三種方法實(shí)現(xiàn):
a、 使用切片操作進(jìn)行拷貝 - -slice operation
(注:切片技術(shù)應(yīng)用于所有的序列,包括:列表、字符串、元祖 ,但切片不能應(yīng)用于字典。對(duì)字典只能使用D.copy()
方法或D.deepcopy()
方法.)
b、 使用工廠函數(shù)進(jìn)行拷貝,list / dir / set - -factoryfunction
c、 copy.copy()
–use copymodule
在復(fù)制的時(shí)候,使用的是淺拷貝,復(fù)制了對(duì)象,但是對(duì)象中的元素,依然使用引用。
如下所示:
a = [1,2,3,['a','b','c']]
#coding=utf-8 import copy #1.切片操作 print('--- 切片操作?。?) b = a[:] print('a = %s\tid(a) = %s'%(a,id(a))) print('b = %s\tid(b) = %s'%(b,id(b))) #2.使用工廠函數(shù) print('--- 使用工廠函數(shù)?。?) c = list(a) print('a = %s\tid(a) = %s'%(a,id(a))) print('c = %s\tid(c) = %s'%(c,id(c))) #3.copy.copy() print('--- copy.copy()?。?) d = copy.copy(a) print('a = %s\tid(a) = %s'%(a,id(a))) print('d = %s\tid(d) = %s'%(d,id(d)))
運(yùn)行結(jié)果:
--- 切片操作?。?br /> a = [1, 2, 3, ['a', 'b', 'c']] id(a) = 140676047022088
b = [1, 2, 3, ['a', 'b', 'c']] id(b) = 140676047021320
--- 使用工廠函數(shù)?。?br /> a = [1, 2, 3, ['a', 'b', 'c']] id(a) = 140676047022088
c = [1, 2, 3, ['a', 'b', 'c']] id(c) = 140676047101640
--- copy.copy()?。?br /> a = [1, 2, 3, ['a', 'b', 'c']] id(a) = 140436217635720
d = [1, 2, 3, ['a', 'b', 'c']] id(d) = 140436217656904
在使用淺拷貝的時(shí)候,發(fā)現(xiàn)引用的id都是相同的,但是字符串的id卻發(fā)生了變化,是因?yàn)樵趐ython中,字符串是不可變的,從而在每次進(jìn)行修改的時(shí)候,都是新建一個(gè)對(duì)象,從而引用發(fā)生了變化.
在不可變類型中,數(shù)字和字符串都是不可變類型,從而在每次修改的時(shí)候,都是新創(chuàng)建一個(gè)對(duì)象。
3、模塊
核心模塊:copy
淺拷貝和深拷貝的操作都可以在copy模塊中找到,其實(shí)copy模塊中只有兩個(gè)函數(shù)可用,copy()進(jìn)行淺拷貝操作,而deepcopy()進(jìn)行深拷貝操作.
如下所示:
#coding=utf-8 import copy a = [1,2,3,['a','b','c']] #淺拷貝拷貝的是外層即頂級(jí)對(duì)象,對(duì)于內(nèi)層只拷貝引用 #所以在a的外層增加了元素,而c并沒(méi)有變化.而在a的內(nèi)層增加元素后,c發(fā)生了同樣的變化.(回顧b=a) print('*'*50) print('--- c = copy.copy(a)---') c = copy.copy(a) print('a = %s'%a) print('c = %s'%c) a.append(4) print('---外層a增加了元素4---') print('a = %s'%a) print('c = %s'%c) print('---內(nèi)層增加了元素"d"---') a[3].append('d') print('a = %s'%a) print('c = %s'%c) #深拷貝會(huì)遞歸的拷貝所有內(nèi)容,將所有的內(nèi)容都獨(dú)自拷貝了一份. #故而,無(wú)論a的外層還是內(nèi)層發(fā)生變化,都不會(huì)影響到d. print('*'*50) print('--- d = copy.deepcopy(a) ---') d = copy.deepcopy(a) print('a = %s'%a) print('d = %s'%d) a.append(5) print('---外層a增加了元素5---') print('a = %s'%a) print('d = %s'%d) print('---內(nèi)層增加了元素"e"---') a[3].append('e') print('a = %s'%a) print('d = %s'%d)
運(yùn)行如下:
**************************************************
--- c = copy.copy(a)---
a = [1, 2, 3, ['a', 'b', 'c']]
c = [1, 2, 3, ['a', 'b', 'c']]
---外層a增加了元素4---
a = [1, 2, 3, ['a', 'b', 'c'], 4]
c = [1, 2, 3, ['a', 'b', 'c']]
---內(nèi)層增加了元素"d"---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
c = [1, 2, 3, ['a', 'b', 'c', 'd']]
**************************************************
--- d = copy.deepcopy(a) ---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
---外層a增加了元素5---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4, 5]
d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
---內(nèi)層增加了元素"e"---
a = [1, 2, 3, ['a', 'b', 'c', 'd', 'e'], 4, 5]
d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
4、拷貝的警告
第一:非容器類型(比如數(shù)字,字符串和其他原子類型的對(duì)象,例如代碼,類型和xrange對(duì)象等)沒(méi)有拷貝一說(shuō),淺拷貝是完全用切片操作來(lái)完成的。
第二:如果元組變量只包含原子類型對(duì)象,那么深拷貝將不會(huì)進(jìn)行。
#coding=utf-8 import copy a = (1,2,3) print('*'*50) print('--- c = copy.copy(a)---') c = copy.copy(a) print(a,id(a)) print(c,id(c)) print('*'*50) print('--- d = copy.deepcopy(a) ---') d = copy.deepcopy(a) print(a,id(a)) print(d,id(c))
運(yùn)行如下:
**************************************************
--- c = copy.copy(a)---
(1, 2, 3) 140394676674992
(1, 2, 3) 140394676674992
**************************************************
--- d = copy.deepcopy(a) ---
(1, 2, 3) 140394676674992
(1, 2, 3) 140394676674992
可見(jiàn):
對(duì)于可變類型來(lái)說(shuō),深拷貝和淺拷貝是不同的.
而對(duì)于不可變類型來(lái)說(shuō),深拷貝和淺拷貝的結(jié)果相同!
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)與進(jìn)階教程》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python編碼操作技巧總結(jié)》及《Python入門(mén)與進(jìn)階經(jīng)典教程》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
- Python 拷貝對(duì)象(深拷貝deepcopy與淺拷貝copy)
- Python對(duì)象的深拷貝和淺拷貝詳解
- Python中的賦值、淺拷貝、深拷貝介紹
- 對(duì)Python中列表和數(shù)組的賦值,淺拷貝和深拷貝的實(shí)例講解
- 深入理解python中的淺拷貝和深拷貝
- 淺談Python淺拷貝、深拷貝及引用機(jī)制
- Python中的復(fù)制操作及copy模塊中的淺拷貝與深拷貝方法
- Python中字典的淺拷貝與深拷貝用法實(shí)例分析
- 深入淺析Python中l(wèi)ist的復(fù)制及深拷貝與淺拷貝
- 詳解Python核心編程中的淺拷貝與深拷貝
- Python中淺拷貝copy與深拷貝deepcopy的簡(jiǎn)單理解
相關(guān)文章
詳解opencv Python特征檢測(cè)及K-最近鄰匹配
這篇文章主要介紹了詳解opencv Python特征檢測(cè)及K-最近鄰匹配,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Python3 實(shí)現(xiàn)將bytes圖片轉(zhuǎn)jpg格式
這篇文章主要介紹了Python3 實(shí)現(xiàn)將bytes圖片轉(zhuǎn)jpg格式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03python使用pygame模塊實(shí)現(xiàn)坦克大戰(zhàn)游戲
這篇文章主要為大家詳細(xì)介紹了python使用pygame模塊實(shí)現(xiàn)坦克大戰(zhàn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05python實(shí)現(xiàn)CSF地面點(diǎn)濾波算法原理解析
這篇文章主要介紹了python實(shí)現(xiàn)CSF地面點(diǎn)濾波算法原理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08利用Python實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼處理
這篇文章主要介紹了利用Python實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼處理,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06Python深度學(xué)習(xí)pytorch卷積神經(jīng)網(wǎng)絡(luò)LeNet
這篇文章主要為大家講解了Python深度學(xué)習(xí)中的pytorch卷積神經(jīng)網(wǎng)絡(luò)LeNet的示例解析,有需要的朋友可以借鑒參考下希望能夠有所幫助2021-10-10