python淺拷貝與深拷貝使用方法詳解
淺拷貝和深拷貝在面試和日常的開(kāi)發(fā)中都會(huì)經(jīng)常遇到
我們就從 對(duì)象賦值、淺拷貝、深拷貝 三個(gè)方面來(lái)講
一、對(duì)象賦值
In [1]: list1 = [1, 2, ['a', 'b']] list2 = list1 print(list1) print(list2) [1, 2, ['a', 'b']] [1, 2, ['a', 'b']] In [2]: list1[0] = 3 print(list1) print(list2) [3, 2, ['a', 'b']] [3, 2, ['a', 'b']] In [3]: list2[1]=[1,2] print(list1) print(list2) [3, [1, 2], ['a', 'b']] [3, [1, 2], ['a', 'b']] In [4]: print(id(list1)) print(id(list2)) 1742901832264 1742901832264
結(jié)論:直接對(duì)象賦值,兩個(gè)對(duì)象的地址是一樣的,也就是這兩個(gè)變量指向是同一個(gè)對(duì)象,兩個(gè)變量會(huì)同步變化
二、淺拷貝
In [5]: import copy A = [1, 'a', ['a', 'b']] # B = A.copy() # 淺拷貝 B = copy.copy(A) # 淺拷貝 print(A) print(B) print(id(A)) print(id(B)) [1, 'a', ['a', 'b']] [1, 'a', ['a', 'b']] 1742901926344 1742901925512 兩個(gè)對(duì)象的內(nèi)存地址不一樣,也就是不是同一個(gè)對(duì)象 In [6]: # 循環(huán)分別打印每個(gè)對(duì)象中的成員的地址 # 打印A for i in A: print("值 {} 的地址是:{}".format(i,id(i))) 值 1 的地址是:140724000563600 值 a 的地址是:1742860054320 值 ['a', 'b'] 的地址是:1742901889800 In [7]: # 循環(huán)分別打印每個(gè)對(duì)象中的成員的地址 # 打印B for i in B: print("值 {} 的地址是:{}".format(i,id(i))) 值 1 的地址是:140724000563600 值 a 的地址是:1742860054320 值 ['a', 'b'] 的地址是:1742901889800
int類型的1和字符串型的a都是不可變數(shù)據(jù)類型,不可變數(shù)據(jù)類型值一樣,地址一樣,值不一樣,地址就不一樣
列表[‘a’, ‘b’]是可變數(shù)據(jù)類型,可變數(shù)據(jù)類型是 變量中數(shù)據(jù)變的時(shí)候,地址不會(huì)變,值相同的兩個(gè)對(duì)象,地址是不一樣的,如果地址一樣,表示指的是同一個(gè)對(duì)象
現(xiàn)在 A[2] 和 B[2] 指向的是同一個(gè)地址,說(shuō)明是同一個(gè)列表,一個(gè)改變,另外的一個(gè)也會(huì)同步改變
通常來(lái)講不可變?cè)匕?/p>
int,float,complex,long,str,unicode,tuple
In [8]: # 在 A[2] 中增加元素 A[2].append(3) print(A) print(B) [1, 'a', ['a', 'b', 3]] [1, 'a', ['a', 'b', 3]] In [9]: # 向A中增加元素 A.append(3) print(A) print(B) [1, 'a', ['a', 'b', 3], 3] [1, 'a', ['a', 'b', 3]] In [10]: A[0]=2 print(A) print(B) [2, 'a', ['a', 'b', 3], 3] [1, 'a', ['a', 'b', 3]]
淺拷貝(copy.copy()):拷貝父對(duì)象,不會(huì)拷貝對(duì)象的內(nèi)部的子對(duì)象,也就是子對(duì)象共用
如果子對(duì)象是不可變數(shù)據(jù)類型,那么復(fù)制的對(duì)象和原來(lái)的對(duì)象互不影響
如果是可變數(shù)據(jù)類型,那么復(fù)制的對(duì)象和原來(lái)的對(duì)象共用
In [11]: A[2]=[1,2] print(A) print(B) [2, 'a', [1, 2], 3] [1, 'a', ['a', 'b', 3]] In [12]: print(id(A[2])) print(id(B[2])) 1742901889416 1742901889800
可以看到 現(xiàn)在 A[2] 和 B[2] 的地址不一樣了,那么他們就互不影響了
其實(shí)看兩個(gè)可變數(shù)據(jù)類型是否互相影響,就是看他們的地址是否一樣
三、深拷貝
In [13]: m = [1, 'a', ['a', 'b']] n = copy.deepcopy(m) print(m) print(n) print(id(m)) print(id(n)) [1, 'a', ['a', 'b']] [1, 'a', ['a', 'b']] 1742900283720 1742900260680 In [14]: # 循環(huán)分別打印每個(gè)對(duì)象中的成員的地址 # 打印m for i in m: print("值 {} 的地址是:{}".format(i,id(i))) 值 1 的地址是:140724000563600 值 a 的地址是:1742860054320 值 ['a', 'b'] 的地址是:1742900341320 In [15]: # 循環(huán)分別打印每個(gè)對(duì)象中的成員的地址 # 打印n for i in n: print("值 {} 的地址是:{}".format(i,id(i))) 值 1 的地址是:140724000563600 值 a 的地址是:1742860054320 值 ['a', 'b'] 的地址是:1742900283208
可以看到,m和n兩個(gè)對(duì)象本身的地址是不一樣的,
并且m和n中成員中的可變數(shù)據(jù)類型的地址也是不一樣的,所以它們兩個(gè)是完全互不影響的
''' 學(xué)習(xí)中遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流群:711312441 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)! ''' In [16]: m[2].append(3) n[1]=5 print(m) print(n) [1, 'a', ['a', 'b', 3]] [1, 5, ['a', 'b']]
淺拷貝(copy.copy()):拷貝父對(duì)象,不會(huì)拷貝對(duì)象的內(nèi)部的子對(duì)象,也就是子對(duì)象共用
- 如果子對(duì)象是不可變數(shù)據(jù)類型,那么復(fù)制的對(duì)象和原來(lái)的對(duì)象互不影響
- 如果是可變數(shù)據(jù)類型,那么復(fù)制的對(duì)象和原來(lái)的對(duì)象共用
深拷貝(copy.deepcopy()):完全拷貝父對(duì)象跟子對(duì)象,復(fù)制的對(duì)象和原來(lái)的對(duì)象互不相關(guān)
四、深入解析
1、b = a.copy(): 淺拷貝, a 和 b 是一個(gè)獨(dú)立的對(duì)象,但他們的子對(duì)象還是指向統(tǒng)一對(duì)象(是引用)。
2、b = copy.deepcopy(a): 深度拷貝, a 和 b 完全拷貝了父對(duì)象及其子對(duì)象,兩者是完全獨(dú)立的。
到此這篇關(guān)于python淺拷貝與深拷貝使用方法詳解的文章就介紹到這了,更多相關(guān)python淺拷貝與深拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python圖像處理模塊ndimage用法實(shí)例分析
這篇文章主要介紹了Python圖像處理模塊ndimage用法,結(jié)合實(shí)例形式分析了Python圖像處理模塊ndimage基本功能及常見(jiàn)的圖形運(yùn)算操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-09-09python使用win32com庫(kù)播放mp3文件的方法
這篇文章主要介紹了python使用win32com庫(kù)播放mp3文件的方法,涉及Python使用win32com庫(kù)操作音頻文件的相關(guān)技巧,需要的朋友可以參考下2015-05-05python-yml文件讀寫(xiě)與xml文件讀寫(xiě)
這篇文章主要介紹了python-yml文件讀寫(xiě)與xml文件讀寫(xiě),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08python使用pyshark庫(kù)捕獲數(shù)據(jù)包的示例詳解
PyShark是一個(gè)基于Python的網(wǎng)絡(luò)數(shù)據(jù)包分析工具庫(kù),它允許用戶捕獲、解碼和分析實(shí)時(shí)網(wǎng)絡(luò)流量,特別是Wi-Fi和TCP/IP協(xié)議的數(shù)據(jù),所以本文給大家介紹了python使用pyshark庫(kù)捕獲數(shù)據(jù)包的示例,需要的朋友可以參考下2024-08-08