您好,登錄后才能下訂單哦!
本文實例講述了Python深拷貝與淺拷貝用法。分享給大家供大家參考,具體如下:
1、對象的賦值
對象的賦值實際上是對象之間的引用:當創建一個對象,然后將這個對象賦值給另外一個變量的時候,python并沒有拷貝這個對象,而只是拷貝了這個對象的引用。
當對對象做賦值或者是參數傳遞或者作為返回值的時候,總是傳遞原始對象的引用,而不是一個副本。如下所示:
在python中將一個變量賦值給另一個變量,傳遞的是引用.無論是a的內層變化還是外層變化,b都會發生同樣的變化.因為b和a指向了同一個引用.類似于c語言中的同一片內存地址.
#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('--- 內層增加了元素"d" ---') a[3].append('d') print('a = %s'%a) print('b = %s'%b)
運行結果:
**************************************************
--- 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]
--- 內層增加了元素'd' ---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
b = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
2、對象的復制
當你想修改一個對象,而且讓原始的對象不受影響的時候,那么就需要使用到對象的復制,對象的復制可以通過三種方法實現:
a、 使用切片操作進行拷貝 - -slice operation
(注:切片技術應用于所有的序列,包括:列表、字符串、元祖 ,但切片不能應用于字典。對字典只能使用D.copy()
方法或D.deepcopy()
方法.)
b、 使用工廠函數進行拷貝,list / dir / set - -factoryfunction
c、 copy.copy()
–use copymodule
在復制的時候,使用的是淺拷貝,復制了對象,但是對象中的元素,依然使用引用。
如下所示:
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.使用工廠函數 print('--- 使用工廠函數 ---') 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)))
運行結果:
--- 切片操作 ---
a = [1, 2, 3, ['a', 'b', 'c']] id(a) = 140676047022088
b = [1, 2, 3, ['a', 'b', 'c']] id(b) = 140676047021320
--- 使用工廠函數 ---
a = [1, 2, 3, ['a', 'b', 'c']] id(a) = 140676047022088
c = [1, 2, 3, ['a', 'b', 'c']] id(c) = 140676047101640
--- copy.copy() ---
a = [1, 2, 3, ['a', 'b', 'c']] id(a) = 140436217635720
d = [1, 2, 3, ['a', 'b', 'c']] id(d) = 140436217656904
在使用淺拷貝的時候,發現引用的id都是相同的,但是字符串的id卻發生了變化,是因為在python中,字符串是不可變的,從而在每次進行修改的時候,都是新建一個對象,從而引用發生了變化.
在不可變類型中,數字和字符串都是不可變類型,從而在每次修改的時候,都是新創建一個對象。
3、模塊
核心模塊:copy
淺拷貝和深拷貝的操作都可以在copy模塊中找到,其實copy模塊中只有兩個函數可用,copy()進行淺拷貝操作,而deepcopy()進行深拷貝操作.
如下所示:
#coding=utf-8 import copy a = [1,2,3,['a','b','c']] #淺拷貝拷貝的是外層即頂級對象,對于內層只拷貝引用 #所以在a的外層增加了元素,而c并沒有變化.而在a的內層增加元素后,c發生了同樣的變化.(回顧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('---內層增加了元素"d"---') a[3].append('d') print('a = %s'%a) print('c = %s'%c) #深拷貝會遞歸的拷貝所有內容,將所有的內容都獨自拷貝了一份. #故而,無論a的外層還是內層發生變化,都不會影響到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('---內層增加了元素"e"---') a[3].append('e') print('a = %s'%a) print('d = %s'%d)
運行如下:
**************************************************
--- 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']]
---內層增加了元素"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]
---內層增加了元素"e"---
a = [1, 2, 3, ['a', 'b', 'c', 'd', 'e'], 4, 5]
d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
4、拷貝的警告
第一:非容器類型(比如數字,字符串和其他原子類型的對象,例如代碼,類型和xrange對象等)沒有拷貝一說,淺拷貝是完全用切片操作來完成的。
第二:如果元組變量只包含原子類型對象,那么深拷貝將不會進行。
#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))
運行如下:
**************************************************
--- c = copy.copy(a)---
(1, 2, 3) 140394676674992
(1, 2, 3) 140394676674992
**************************************************
--- d = copy.deepcopy(a) ---
(1, 2, 3) 140394676674992
(1, 2, 3) 140394676674992
可見:
對于可變類型來說,深拷貝和淺拷貝是不同的.
而對于不可變類型來說,深拷貝和淺拷貝的結果相同!
更多關于Python相關內容感興趣的讀者可查看本站專題:《Python面向對象程序設計入門與進階教程》、《Python數據結構與算法教程》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》、《Python編碼操作技巧總結》及《Python入門與進階經典教程》
希望本文所述對大家Python程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。