python中淺復(fù)制copy與深復(fù)制deepcopy
簡(jiǎn)介
在使用列表或者字典進(jìn)行傳遞參數(shù)的時(shí)候,可能會(huì)遇到函數(shù)改變了列表的值,但是不希望印象原來(lái)列表中的值,所以,python提供了copy模塊,其中包含copy()和deepcopy()兩函數(shù),顧名思義copy()指的就是淺復(fù)制,deepcopy()指的就是深復(fù)制。
copy.copy()詳解
copy.copy()主要是用來(lái)復(fù)制一維列表或者一維元組,即 像[‘A’,‘B’,‘C’,‘D’]這種,如果列表中再套列表,比如這種[‘A’,‘B’,[‘d’,‘e’,‘f’],‘C’] 就不能進(jìn)行復(fù)制更改。下面來(lái)做一個(gè)簡(jiǎn)單的測(cè)試。
import copy lis_A = ['A','B','C','D'] lis_B = ['A','B',['d','e','f'],'C'] # 使用copy.copy()復(fù)制lis_A copy_A = copy.copy(lis_A) print('lis_A的值', lis_A) print('copy_A的值', copy_A) # 打印出lis_A和copy_A的ID值 print('lis_A的ID值', id(lis_A)) print('copy_A的ID值', id(copy_A))
輸出結(jié)果是:
lis_A的值 ['A', 'B', 'C', 'D']
copy_A的值 ['A', 'B', 'C', 'D']
lis_A的ID值 1347357010368
copy_A的ID值 1347357613888
這里可以看出。copy_A的值與lis_A的值是一樣的,但是它們的ID值是不一樣的,說(shuō)明copy_A指向了一個(gè)獨(dú)立的列表。那么改變copy_A的值是不會(huì)去影響lis_A的列表的值,可以做試驗(yàn):
從上面可以看出,我改變了copy_A中的 ‘B’ 的值,但是并沒(méi)有影響到lis_A中的值。
使用copy()復(fù)制嵌套列表會(huì)是什么結(jié)果呢?
lis_B = ['A', 'B', ['d', 'e', 'f'], 'C'] # 使用copy_B復(fù)制 lis_B copy_B = copy.copy(lis_B) # 分別打印lis_B和copy_B的值 print('lis_B的值', lis_B) print('copy_B的值', copy_B) # 打印出lis_B和copy_B的ID值 print('lis_B的ID值', id(lis_B)) print('copy_B的ID值', id(copy_B))
輸出的結(jié)果是:
lis_B的值 ['A', 'B', ['d', 'e', 'f'], 'C']
copy_B的值 ['A', 'B', ['d', 'e', 'f'], 'C']
lis_B的ID值 2116281195712
copy_B的ID值 2116321275968
咦,也復(fù)制出來(lái)了呀,怎么回事?別急,接著看,我們 改變一下copy_B中的 B 的值試試。
lis_B = ['A', 'B', ['d', 'e', 'f'], 'C'] # 使用copy_B復(fù)制 lis_B copy_B = copy.copy(lis_B) # 改變copy_B中的 B 的值 copy_B[1] = '改變B' # 分別打印lis_B和copy_B的值 print('lis_B的值', lis_B) print('copy_B的值', copy_B) # 打印出lis_B和copy_B的ID值 print('lis_B的ID值', id(lis_B)) print('copy_B的ID值', id(copy_B))
輸出結(jié)果:
lis_B的值 ['A', 'B', ['d', 'e', 'f'], 'C']
copy_B的值 ['A', '改變B', ['d', 'e', 'f'], 'C']
lis_B的ID值 2258614705408
copy_B的ID值 2258654720640
從上可以看出,copy_B中B的值已經(jīng)被改變了,怎么回事?要翻車(chē)了嗎?我們?cè)俑淖円幌耤opy_B中的的整個(gè)列表試試?
lis_B = ['A', 'B', ['d', 'e', 'f'], 'C'] # 使用copy_B復(fù)制 lis_B copy_B = copy.copy(lis_B) # # 改變copy_B中的 B 的值 # copy_B[1] = '改變B' # 改變lis_B中嵌套的列表 試試? copy_B[2] = ['1', '2', '3'] # 分別打印lis_B和copy_B的值 print('lis_B的值', lis_B) print('copy_B的值', copy_B) # 打印出lis_B和copy_B的ID值 print('lis_B的ID值', id(lis_B)) print('copy_B的ID值', id(copy_B))
輸出的結(jié)果是:
lis_B的值 ['A', 'B', ['d', 'e', 'f'], 'C']
copy_B的值 ['A', 'B', ['1', '2', '3'], 'C']
lis_B的ID值 1860576959872
copy_B的ID值 1860618301312
copy_B的列表也變了。在改變一下copy_B嵌套列表 [‘1’, ‘2’, ‘3’] 中的‘2’的值呢?
lis_B = ['A', 'B', ['d', 'e', 'f'], 'C'] # 使用copy_B復(fù)制 lis_B copy_B = copy.copy(lis_B) # # 改變copy_B中的 B 的值 # copy_B[1] = '改變B' # 改變lis_B中嵌套的列表 試試? copy_B[2] = ['1', '2', '3'] # 改變lis_B中嵌套的列表中的值 試試? copy_B[2][1] = '改變2' # 分別打印lis_B和copy_B的值 print('lis_B的值', lis_B) print('copy_B的值', copy_B) # 打印出lis_B和copy_B的ID值 print('lis_B的ID值', id(lis_B)) print('copy_B的ID值', id(copy_B))
輸出結(jié)果:
lis_B的值 ['A', 'B', ['d', 'e', 'f'], 'C']
copy_B的值 ['A', 'B', ['1', '改變2', '3'], 'C']
lis_B的ID值 2763457256768
copy_B的ID值 2763497140352
啊,‘2’也改變了,沒(méi)有影響lis_B的值,怎么回事啊,翻車(chē)了嗎?我們直接改變復(fù)制出來(lái)的copy_B的嵌套列表的值,不先改變嵌套列表試試呢。
lis_B = ['A', 'B', ['d', 'e', 'f'], 'C'] # 使用copy_B復(fù)制 lis_B copy_B = copy.copy(lis_B) # # 改變copy_B中的 B 的值 # copy_B[1] = '改變B' # # 改變lis_B中嵌套的列表 試試? # copy_B[2] = ['1', '2', '3'] # # 改變lis_B中嵌套的列表中的值 試試? # copy_B[2][1] = '改變2' # 直接改變copy_B的值,將上兩步注釋掉,此時(shí)copy_B = lis_B = ['A', 'B', ['d', 'e', 'f'], 'C'] copy_B[2][1] = '改變2' # 改變2 是改變 ['A', 'B', ['d', 'e', 'f'], 'C'] 中的 e # 分別打印lis_B和copy_B的值 print('lis_B的值', lis_B) print('copy_B的值', copy_B) # 打印出lis_B和copy_B的ID值 print('lis_B的ID值', id(lis_B)) print('copy_B的ID值', id(copy_B))
輸出結(jié)果:
lis_B的值 ['A', 'B', ['d', '改變2', 'f'], 'C']
copy_B的值 ['A', 'B', ['d', '改變2', 'f'], 'C']
lis_B的ID值 2342836779328
copy_B的ID值 2342878850496
神奇的一幕發(fā)生了,改變的是copy_B中的e的值,但是lis_B中e的值也發(fā)生了改變。
看懂了嗎?這就是使用copy.copy()復(fù)制嵌套列表的弊端,表面看復(fù)制了lis_B[但是有沒(méi)有完全復(fù)制 lis_B ,這種情況就要使用deepcopy()來(lái)進(jìn)行復(fù)制。
但是,為什么之前的情況.為什么能將嵌套列表[‘d’, ‘e’, ‘f’]改為[‘1’, ‘2’, ‘3’],再將[‘1’, ‘2’, ‘3’]的 ‘2’ 變?yōu)?‘改變2’呢。
(1)為什么能將 [‘A’, ‘B’, [‘d’, ‘e’, ‘f’], ‘C’] 變?yōu)?[‘A’, ‘B’, [‘1’, ‘2’, ‘3’], ‘C’]?
簡(jiǎn)單理解,在整體改變[‘d’, ‘e’, ‘f’] 可以把他看做為一個(gè)整體,由X來(lái)代替,[‘1’, ‘2’, ‘3’]由Y來(lái)代替。所以此時(shí)的變更相當(dāng)于把[‘A’, ‘B’, X, ‘C’] 變更為 [‘A’, ‘B’, Y, ‘C’]。實(shí)際上變更的還是一維列表。copy.copy()是可以復(fù)制一維列表的。
(2)為什么 copy_B = [‘A’, ‘B’, [‘d’, ‘e’, ‘f’], ‘C’] 變?yōu)?[‘A’, ‘B’, [‘1’, ‘2’, ‘3’], ‘C’],再去變[‘1’, ‘2’, ‘3’]中的‘2’時(shí),不會(huì)影響lis_B = [‘A’, ‘B’, [‘d’, ‘e’, ‘f’], ‘C’]?
原因是第一步將 copy_B = [‘A’, ‘B’, [‘d’, ‘e’, ‘f’], ‘C’] 變?yōu)?[‘A’, ‘B’, [‘1’, ‘2’, ‘3’], ‘C’] 此時(shí)已經(jīng)產(chǎn)生了一個(gè)新的列表 [‘A’, ‘B’, [‘1’, ‘2’, ‘3’], ‘C’] ,與列表 lis_B = [‘A’, ‘B’, [‘d’, ‘e’, ‘f’], ‘C’] 是兩個(gè)完全不相同的兩個(gè)列表。自然不回影響。
如果說(shuō)有個(gè)列表 lis_C = [‘A’, ‘B’, [‘d’, ‘e’, ‘f’], [‘x’,‘y’]],先變?yōu)?[‘A’, ‘B’, [‘1’, ‘2’, ‘3’], [‘x’,‘y’]],再去改變 'x’變會(huì)對(duì)源列表產(chǎn)生影響
# 定義一個(gè)lis_C lis_C = ['A', 'B', ['d', 'e', 'f'], ['x', 'y']] # 復(fù)制一個(gè) copy_C copy_C = copy.copy(lis_C) # copy_C = ['A', 'B', ['d', 'e', 'f'], ['x', 'y']] 變?yōu)?['A', 'B', ['1', '2', '3'], ['x', 'y']] copy_C[2] = ['1', '2', '3'] # 在來(lái)改變 ['A', 'B', ['1', '2', '3'], ['x', 'y']] 中 'x'的值 copy_C[3][0] = '改變x' # 分別打印copy_C和copy_C的值 print('lis_C的值', lis_C) print('copy_C的值', copy_C) # 打印出lis_C和copy_C的ID值 print('lis_C的ID值', id(lis_C)) print('copy_C的ID值', id(copy_C))
輸出結(jié)果:
lis_C的值 ['A', 'B', ['d', 'e', 'f'], ['改變x', 'y']]
copy_C的值 ['A', 'B', ['1', '2', '3'], ['改變x', 'y']]
lis_C的ID值 2790729135616
copy_C的ID值 2790729135424
從可以看出,copy_C 中[‘d’, ‘e’, ‘f’] 變成[ ‘1’, ‘2’, ‘3’]時(shí),并不影響lis_C,在 將 [‘x’, ‘y’] 變?yōu)?[‘改變x’, ‘y’]時(shí)就會(huì)印象lis_C
copy.deepcopy()詳解
上面說(shuō)到,在使用copy.copy()復(fù)制嵌套的二維列表[‘A’, ‘B’, [‘d’, ‘e’, ‘f’], [‘x’, ‘y’]],然后改變嵌套列表中的值是,會(huì)影響到源列表的值,那么使用copy.deepcopy()是否會(huì)影響源列表呢?
import copy # 定義一個(gè)lis_D lis_D = ['A', 'B', ['d', 'e', 'f'], ['x', 'y']] # 使用deepcopy()復(fù)制一個(gè) copy_C copy_D = copy.deepcopy(lis_D) # 直接改變 copy_D 中嵌套列表 ['d', 'e', 'f'] 中的值d copy_D[2][0] = '改變d' # 分別打印copy_D和copy_D的值 print('lis_D的值', lis_D) print('copy_D的值', copy_D) # 打印出lis_D和copy_D的ID值 print('lis_D的ID值', id(lis_D)) print('copy_D的ID值', id(copy_D))
輸出結(jié)果:
lis_D的值 ['A', 'B', ['d', 'e', 'f'], ['x', 'y']]
copy_D的值 ['A', 'B', ['改變d', 'e', 'f'], ['x', 'y']]
lis_D的ID值 2335362856512
copy_D的ID值 2335362856320
從上述結(jié)果可以很明顯的看出,使用deepcopy()復(fù)制列表lis_之后,直接改變二維列表中的值 d,不會(huì)影響到源列表lis_D
到此這篇關(guān)于python中淺復(fù)制copy與深復(fù)制deepcopy的文章就介紹到這了,更多相關(guān)python淺復(fù)制與深復(fù)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)尋找最長(zhǎng)回文子序列的方法
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)尋找最長(zhǎng)回文子序列的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Python Numpy:找到list中的np.nan值方法
今天小編就為大家分享一篇Python Numpy:找到list中的np.nan值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10使用Python在Excel工作表中創(chuàng)建數(shù)據(jù)透視表的方法
在數(shù)據(jù)處理和分析工作中,Excel作為一個(gè)廣泛使用的工具,提供了強(qiáng)大的功能來(lái)管理和解析數(shù)據(jù),當(dāng)面對(duì)大量復(fù)雜的數(shù)據(jù)集時(shí),為了更高效地總結(jié)、分析和展示數(shù)據(jù),創(chuàng)建數(shù)據(jù)透視表成為一種不可或缺的方法,本文將介紹如何使用Python在Excel工作表中創(chuàng)建數(shù)據(jù)透視表2025-01-01Python進(jìn)程間通信 multiProcessing Queue隊(duì)列實(shí)現(xiàn)詳解
這篇文章主要介紹了python進(jìn)程間通信 mulitiProcessing Queue隊(duì)列實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Python基礎(chǔ)學(xué)習(xí)之條件控制語(yǔ)句小結(jié)
如果我需要設(shè)置一個(gè)死循環(huán),然后靠條件來(lái)終止,怎么辦?一個(gè)很簡(jiǎn)單的問(wèn)題,但是我卻沒(méi)有說(shuō),這一篇本應(yīng)該在分支控制語(yǔ)句里面的,現(xiàn)在只能拿出來(lái)水文再寫(xiě)一篇了,需要的朋友可以參考下2021-05-05