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ì)象中無 復(fù)雜 子對(duì)象,原來值的改變并不會(huì)影響淺復(fù)制的值,同時(shí)淺復(fù)制的值改變也并不會(huì)影響原來的值。原來值的id值與淺復(fù)制原來的值不同。
第二種情況:復(fù)制的對(duì)象中有 復(fù)雜 子對(duì)象 (例如列表中的一個(gè)子元素是一個(gè)列表), 改變?cè)瓉淼闹?中的復(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編寫通訊錄通過數(shù)據(jù)庫存儲(chǔ)實(shí)現(xiàn)模糊查詢功能
數(shù)據(jù)庫存儲(chǔ)通訊錄,要求按姓名/電話號(hào)碼查詢,查詢條件只有一個(gè)輸入入口,自動(dòng)識(shí)別輸入的是姓名還是號(hào)碼,允許模糊查詢。這篇文章主要介紹了Python編寫通訊錄,支持模糊查詢,利用數(shù)據(jù)庫存儲(chǔ),需要的朋友可以參考下2019-07-07非常簡(jiǎn)單的Python識(shí)別圖片驗(yàn)證碼實(shí)現(xiàn)過程
這篇文章主要介紹了Python驗(yàn)證碼識(shí)別實(shí)現(xiàn)過程,只需要幾行代碼就可以實(shí)現(xiàn),過程非常簡(jiǎn)單,有需要的朋友可以借鑒參考下,希望可以有所幫助2021-09-09如何利用Python獲取鼠標(biāo)的實(shí)時(shí)位置
這篇文章主要給大家介紹了關(guān)于如何利用Python獲取鼠標(biāo)的實(shí)時(shí)位置的相關(guān)資料,主要利用的是pyautogui,一個(gè)自動(dòng)化鍵鼠操作的Python類庫,需要的朋友可以參考下2022-01-01Python調(diào)用C語言的方法【基于ctypes模塊】
這篇文章主要介紹了Python調(diào)用C語言的方法,涉及Python基于ctypes模塊調(diào)用C語言編譯后的動(dòng)態(tài)鏈接庫文件相關(guān)操作技巧,需要的朋友可以參考下2018-01-01用python實(shí)現(xiàn)一個(gè)文件搜索工具
大家好,本篇文章主要講的是用python實(shí)現(xiàn)一個(gè)搜索工具,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01