Python中copy和deepcopy的使用分析
一、定義
淺拷貝:創(chuàng)建一個(gè)新的對(duì)象,只拷貝子對(duì)象的引用(內(nèi)部的內(nèi)存地址都不相同)。這意味著,如果原對(duì)象的子對(duì)象發(fā)生變化,拷貝后的對(duì)象也會(huì)受到影響。
深拷貝:創(chuàng)建一個(gè)新的對(duì)象,并遞歸地拷貝原對(duì)象的所有子對(duì)象(內(nèi)部以及外部的內(nèi)存地址都不相同)。這意味著,即使原對(duì)象的子對(duì)象發(fā)生變化,拷貝后的對(duì)象也不會(huì)受到影響。
二、區(qū)別
淺拷貝copy:
第一種情況:復(fù)制的 對(duì)象中無(wú) 復(fù)雜 子對(duì)象,原來(lái)值的改變并不會(huì)影響淺復(fù)制的值,同時(shí)淺復(fù)制的值改變也并不會(huì)影響原來(lái)的值。原來(lái)值的id值與淺復(fù)制原來(lái)的值不同。
第二種情況:復(fù)制的對(duì)象中有 復(fù)雜 子對(duì)象 (例如列表中的一個(gè)子元素是一個(gè)列表), 改變?cè)瓉?lái)的值 中的復(fù)雜子對(duì)象的值 ,會(huì)影響淺復(fù)制的值。
深拷貝deepcopy:完全復(fù)制獨(dú)立,包括內(nèi)層列表和字典。
三、代碼分析深淺拷貝
淺拷貝僅拷貝對(duì)象本身
不可變類型的淺拷貝
如果復(fù)制不可變類型的數(shù)據(jù)(字符串、數(shù)值型、布爾值),和“=”賦值情況一樣,淺拷貝的對(duì)象和原數(shù)據(jù)對(duì)象是相同的內(nèi)存地址。
import copy
a = '哈哈'
b = a
c = copy.copy(a)
print('原數(shù)據(jù)的內(nèi)存地址:', id(a))
print('淺拷貝對(duì)象的內(nèi)存地址:', id(c))
print('=賦值對(duì)象的內(nèi)存地址:', id(c))
print('\n')
可變類型的淺拷貝
情況一:不存在嵌套類型的可變類型數(shù)據(jù)(列表、字典、集合)。列表本身的淺拷貝對(duì)象的地址
原對(duì)象的地址是不同的,因?yàn)榱斜硎强勺償?shù)據(jù)類型。因此改變?cè)瓕?duì)象的值并不會(huì)影響淺復(fù)制的
值。
list1 = [1, 2, 3]
list2 = copy.copy(list1)
print('原數(shù)據(jù)的內(nèi)存地址:', id(list1))
print('淺拷貝的內(nèi)存地址:', id(list2))
# 測(cè)試,修改list1對(duì)象元素的值,不會(huì)改變list2的值(相互不影響)
list1[0] = 8
print(list1)
print(list2)
情況二:如果可變類型的數(shù)據(jù)中存在嵌套的結(jié)構(gòu)。淺拷貝只復(fù)制最外層的數(shù)據(jù),導(dǎo)致內(nèi)存地址發(fā)
變化,嵌套數(shù)據(jù)的內(nèi)存地址不會(huì)變。因此改變?cè)瓕?duì)象中的嵌套對(duì)象的值,會(huì)影響淺復(fù)制的值。
list3 = [1, 2, [3, 4, 5]]
list4 = copy.copy(list3)
print('原數(shù)據(jù)的內(nèi)存地址:', id(list3))
print('淺拷貝的內(nèi)存地址:', id(list4))
print('\n')
print('原數(shù)據(jù)的內(nèi)存地址:', id(list3[0]))
print('淺拷貝的內(nèi)存地址:', id(list4[0]))
print('\n')
print('原數(shù)據(jù)的內(nèi)存地址:', id(list3[2]))
print('淺拷貝的內(nèi)存地址:', id(list4[2]))
# 測(cè)試
list3[2][0] = 8 # 改變list3嵌套列表的數(shù)值,淺拷貝的值也發(fā)生變化
print(list3)
print(list4)
深拷貝完全復(fù)制獨(dú)立
不可變類型的深拷貝
number = 5
number2 = copy.deepcopy(number)
print('原數(shù)據(jù)的內(nèi)存地址:', id(number))
print('深拷貝的內(nèi)存地址:', id(number2))
可變類型的深拷貝
原對(duì)象的值和復(fù)制后的值不相互影響。
情況一:不存在嵌套類型的可變類型數(shù)據(jù)(列表、字典、集合)
list1 = [1, 2, 3]
list2 = copy.copy(list1)
list33 = copy.deepcopy(list1)
print('原數(shù)據(jù)的內(nèi)存地址:', id(list1))
print('淺拷貝的內(nèi)存地址:', id(list2))
print('深拷貝的內(nèi)存地址:', id(list33))
情況二:如果可變類型的數(shù)據(jù)中存在嵌套的結(jié)構(gòu)
list3 = [1, 2, [3, 4, 5]]
list4 = copy.copy(list3)
list55 = copy.deepcopy(list3)
print('原數(shù)據(jù)的內(nèi)存地址:', id(list3))
print('淺拷貝的內(nèi)存地址:', id(list4))
print('深拷貝的內(nèi)存地址:', id(list55))
print('\n')
print('原數(shù)據(jù)的內(nèi)存地址:', id(list3[0]))
print('淺拷貝的內(nèi)存地址:', id(list4[0]))
print('深拷貝的內(nèi)存地址:', id(list55[0]))
print('\n')
print('原數(shù)據(jù)的內(nèi)存地址:', id(list3[2]))
print('淺拷貝的內(nèi)存地址:', id(list4[2]))
print('深拷貝的內(nèi)存地址:', id(list55[2]))
四、總結(jié)
只有淺拷貝拷貝有嵌套的可變類型時(shí),改變?cè)瓕?duì)象中嵌套內(nèi)的數(shù)據(jù),拷貝對(duì)象的值也會(huì)改變,即
原對(duì)象與拷貝對(duì)象的值相互影響。
到此這篇關(guān)于Python中copy和deepcopy的使用分析的文章就介紹到這了,更多相關(guān)Python copy deepcopy內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python編寫(xiě)通訊錄通過(guò)數(shù)據(jù)庫(kù)存儲(chǔ)實(shí)現(xiàn)模糊查詢功能
數(shù)據(jù)庫(kù)存儲(chǔ)通訊錄,要求按姓名/電話號(hào)碼查詢,查詢條件只有一個(gè)輸入入口,自動(dòng)識(shí)別輸入的是姓名還是號(hào)碼,允許模糊查詢。這篇文章主要介紹了Python編寫(xiě)通訊錄,支持模糊查詢,利用數(shù)據(jù)庫(kù)存儲(chǔ),需要的朋友可以參考下2019-07-07
非常簡(jiǎn)單的Python識(shí)別圖片驗(yàn)證碼實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了Python驗(yàn)證碼識(shí)別實(shí)現(xiàn)過(guò)程,只需要幾行代碼就可以實(shí)現(xiàn),過(guò)程非常簡(jiǎn)單,有需要的朋友可以借鑒參考下,希望可以有所幫助2021-09-09
如何利用Python獲取鼠標(biāo)的實(shí)時(shí)位置
這篇文章主要給大家介紹了關(guān)于如何利用Python獲取鼠標(biāo)的實(shí)時(shí)位置的相關(guān)資料,主要利用的是pyautogui,一個(gè)自動(dòng)化鍵鼠操作的Python類庫(kù),需要的朋友可以參考下2022-01-01
Python調(diào)用C語(yǔ)言的方法【基于ctypes模塊】
這篇文章主要介紹了Python調(diào)用C語(yǔ)言的方法,涉及Python基于ctypes模塊調(diào)用C語(yǔ)言編譯后的動(dòng)態(tài)鏈接庫(kù)文件相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
用python實(shí)現(xiàn)一個(gè)文件搜索工具
大家好,本篇文章主要講的是用python實(shí)現(xiàn)一個(gè)搜索工具,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01

