python深復制
Ⅰ python3 淺層復制和深層復制有什麼區別
淺復制對象指向同一個內存地址,深復制對象指向不同的內存地址。
Ⅱ 舉例區分Python中的淺復制與深復制
舉例區分Python中的淺復制與深復制
這篇文章主要介紹了舉例區分Python中的淺復制與深復制,是Python入門學習中的重要知識,需要的朋友可以參考下
模塊用於對象的拷貝操作。該模塊非常簡單,只提供了兩個主要的方法: . 與 .deep ,分別表示淺復制與深復制。什麼是淺復制,什麼是深復制,網上有一卡車一卡車的資料,這里不作詳細介紹。復制操作只對復合對象有效。用簡單的例子來分別介紹這兩個方法。
淺復制只復制對象本身,沒有復制該對象所引用的對象。
#coding=gbk
import
l1 = [1, 2, [3, 4]]
l2 = .(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2
#---- 結果 ----
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]
[1, 2, [50, 4]]
同樣的代碼,使用深復制,結果就不一樣:
import
l1 = [1, 2, [3, 4]]
l2 = .deep(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2
#---- 結果 ----
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]
改變的默認行為
在定義類的時候,通過定義____和__deep__方法,可以改變的默認行為。下面是一個簡單的例子:
class CopyObj(object):
def __repr__(self):
return "CopyObj"
def ____(self):
return "Hello"
obj = CopyObj()
obj1 = .(obj)
print obj
print obj1
#---- 結果 ----
CopyObj
Hello
Ⅲ python深拷貝和淺拷貝的區別
這個問題其實網上解答已經很多了,最好說仔細點在什麼地方不理解。
下面一個例子可以看看:
import
a=[1,2,3,4,['a','b']]#原始對象
b=a#賦值,傳對象的引用
c=.(a)#對象拷貝,淺拷貝
d=.deep(a)#對象拷貝,深拷貝
a.append(5)#修改對象a
a[4].append('c')#修改對象a中的['a','b']數組對象
print'a=',a
print'b=',b
print'c=',c
print'd=',d
然後自己想一想輸出都應該是什麼
a是原始對象,作為對照
b是a的引用,和a指向同一個對象
c是a的一個淺拷貝,將a的內容拷貝過來了,就是和a平行的兩個對象了,但是裡面元素如果是對象,僅拷貝其引用,即a[4]變化後c[4]也對應變化了,因為他倆實際指向同一個對象,而a和c指向不同的對象
d則是從頭到尾全部拷貝過來,就連裡面的對象也拷貝了一份,因此a[4]變化而d[4]沒有變化,因為a[4]和d[4]在拷貝的時候值一樣,但是其實已經是兩個對象了。
下面是上面內容的輸出結果。
a=[1,2,3,4,['a','b','c'],5]
b=[1,2,3,4,['a','b','c'],5]
c=[1,2,3,4,['a','b','c']]
d=[1,2,3,4,['a','b']]
Ⅳ Python的復制,深拷貝和淺拷貝的區別
簡單點說
1. . 淺拷貝 只拷貝父對象,不會拷貝對象的內部的子對象。
2. .deep 深拷貝 拷貝對象及其子對象
用一個簡單的例子說明如下:
>>>import
>>>a = [1, 2, 3, 4, ['a', 'b', 'c']]
>>> b = a
>>> c = .(a)
>>> d = .deep(a)
很容易理解:a是一個列表,表內元素a[4]也是一個列表(也就是一個內部子對象);b是對a列表的又一個引用,所以a、b是完全相同的,可以通過id(a)==id(b)證明。
第4行是淺拷貝,第五行是深拷貝,通過id(c)和id(d)可以發現他們不相同,且與id(a)都不相同:
>>> id(a)
19276104
>>> id(b)
19276104
>>> id(c)
19113304
>>> id(d)
19286976
至於如何看深/淺拷貝的區別,可以通過下面的操作來展現:
>>> a.append(5) #操作1
>>> a[4].append('hello') #操作2
這時再查看結果:
>>> a
[1, 2, 0, 4, ['a', 'b', 'c', 'hello'], 5]
>>> b
[1, 2, 0, 4, ['a', 'b', 'c', 'hello'], 5]
>>> c
[1, 2, 3, 4, ['a', 'b', 'c', 'hello']]
>>> d
[1, 2, 3, 4, ['a', 'b', 'c']]
可以發現a、b受了操作1、2的影響,c只受操作2影響,d不受影響。a、b結果相同很好理解。由於c是a的淺拷貝,只拷貝了父對象,因此a的子對象( ['a', 'b', 'c', 'hello'])改變時會影響到c;d是深拷貝,完全不受a的影響
Ⅳ python 為什麼有深拷貝淺拷貝
在寫Python過程中,經常會遇到對象的拷貝,如果不理解淺拷貝和深拷貝的概念,你的代碼就可能出現一些問題。所以,在這里按個人的理解談談它們之間的區別。
一、賦值(assignment)
在《Python FAQ1》一文中,對賦值已經講的很清楚了,關鍵要理解變數與對象的關系。
12345
>>> a = [1, 2, 3]>>> b = a>>> print(id(a), id(b), sep='\n')
在Python中,用一個變數給另一個變數賦值,其實就是給當前內存中的對象增加一個「標簽」而已。
如上例,通過使用內置函數 id() ,可以看出 a 和 b 指向內存中同一個對象。a is b會返回 True 。
二、淺拷貝(shallow )
注意:淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其它對象的對象,如列表,類實例。而對於數字、字元串以及其它「原子」類型,沒有拷貝一說,產生的都是原對象的引用。
所謂「淺拷貝」,是指創建一個新的對象,其內容是原對象中元素的引用。(拷貝組合對象,不拷貝子對象)
常見的淺拷貝有:切片操作、工廠函數、對象的()方法、模塊中的函數。
12345678910
>>> a = [1, 2, 3]>>> b = list(a)>>> print(id(a), id(b)) # a和b身份不同140601785066200 140601784764968>>> for x, y in zip(a, b): # 但它們包含的子對象身份相同... print(id(x), id(y))... 140601911441984 140601911442048
從上面可以明顯的看出來,a 淺拷貝得到 b,a 和 b 指向內存中不同的 list 對象,但它們的元素卻指向相同的 int 對象。這就是淺拷貝!
三、深拷貝(deep )
所謂「深拷貝」,是指創建一個新的對象,然後遞歸的拷貝原對象所包含的子對象。深拷貝出來的對象與原對象沒有任何關聯。
深拷貝只有一種方式:模塊中的deep函數。
1234567891011
>>> import >>> a = [1, 2, 3]>>> b = .deep(a)>>> print(id(a), id(b))140601785065840 140601785066200>>> for x, y in zip(a, b):... print(id(x), id(y))... 140601911441984 140601911442048
看了上面的例子,有人可能會疑惑:
為什麼使用了深拷貝,a和b中元素的id還是一樣呢?
答:這是因為對於不可變對象,當需要一個新的對象時,python可能會返回已經存在的某個類型和值都一致的對象的引用。而且這種機制並不會影響 a 和 b 的相互獨立性,因為當兩個元素指向同一個不可變對象時,對其中一個賦值不會影響另外一個。
我們可以用一個包含可變對象的列表來確切地展示「淺拷貝」與「深拷貝」的區別:
>>> import >>> a = [[1, 2],[5, 6], [8, 9]]>>> b = .(a) # 淺拷貝得到b>>> c = .deep(a) # 深拷貝得到c>>> print(id(a), id(b)) # a 和 b 不同139832578518984 139832578335520>>> for x, y in zip(a, b): # a 和 b 的子對象相同... print(id(x), id(y))... 139832578622816 139832578623104>>> print(id(a), id(c)) # a 和 c 不同139832578518984 139832578622456>>> for x, y in zip(a, c): # a 和 c 的子對象也不同... print(id(x), id(y))... 139832578622816 139832578623392
從這個例子中可以清晰地看出淺拷貝與深拷貝地區別。
總結:
1、賦值:簡單地拷貝對象的引用,兩個對象的id相同。
2、淺拷貝:創建一個新的組合對象,這個新對象與原對象共享內存中的子對象。
3、深拷貝:創建一個新的組合對象,同時遞歸地拷貝所有子對象,新的組合對象與原對象沒有任何關聯。雖然實際上會共享不可變的子對象,但不影響它們的相互獨立性。
淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其它對象的對象,如列表,類實例。而對於數字、字元串以及其它「原子」類型,沒有拷貝一說,產生的都是原對象的引用。
Ⅵ python的復制,深拷貝和淺拷貝的區別
在python中,對象賦值實際上是對象的引用。當創建一個對象,然後把它賦給另一個變數的時候,python並沒有拷貝這個對象,而只是拷貝了這個對象的引用
一般有三種方法,
alist=[1,2,3,["a","b"]]
(1)直接賦值,傳遞對象的引用而已,原始列表改變,被賦值的b也會做相同的改變
>>> b=list
>>> print b
[1, 2, 3, ['a', 'b']]
>>> list.append(5)
>>> alist=[1,2,3,["a","b"]]
>>> b=alist
>>> print b
[1, 2, 3, ['a', 'b']]
>>> alist.append(5)
>>> print alist;print b
[1, 2, 3, ['a', 'b'], 5]
[1, 2, 3, ['a', 'b'], 5]
(2)淺拷貝,沒有拷貝子對象,所以原始數據改變,子對象會改變
>>> import
>>> c=.(alist)
>>> print alist;print c
[1, 2, 3, ['a', 'b']]
[1, 2, 3, ['a', 'b']]
>>> alist.append(5)
>>> print alist;print c
[1, 2, 3, ['a', 'b'], 5]
[1, 2, 3, ['a', 'b']]
>>> alist[3]
['a', 'b']
>>> alist[3].append('cccc')
>>> print alist;print c
[1, 2, 3, ['a', 'b', 'cccc'], 5]
[1, 2, 3, ['a', 'b', 'cccc']] 裡面的子對象被改變了
(3)深拷貝,包含對象裡面的自對象的拷貝,所以原始對象的改變不會造成深拷貝里任何子元素的改變
>>> import
>>> d=.deep(alist)
>>> print alist;print d
[1, 2, 3, ['a', 'b']]
[1, 2, 3, ['a', 'b']]始終沒有改變
>>> alist.append(5)
>>> print alist;print d
[1, 2, 3, ['a', 'b'], 5]
[1, 2, 3, ['a', 'b']]始終沒有改變
>>> alist[3]
['a', 'b']
>>> alist[3].append("ccccc")
>>> print alist;print d
[1, 2, 3, ['a', 'b', 'ccccc'], 5]
[1, 2, 3, ['a', 'b']] 始終沒有改變
Ⅶ python深拷貝為什麼不可變類型id不變
因為拷貝過去的是引用,id當然沒變。
Ⅷ python 深拷貝和淺拷貝的區別
這個問題其實網上解答已經很多了,最好說仔細點在什麼地方不理解。
下面一個例子可以看看:
import
a = [1, 2, 3, 4, ['a', 'b']] #原始對象
b = a #賦值,傳對象的引用
c = .(a) #對象拷貝,淺拷貝
d = .deep(a) #對象拷貝,深拷貝
a.append(5) #修改對象a
a[4].append('c') #修改對象a中的['a', 'b']數組對象
print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d
然後自己想一想輸出都應該是什麼
a是原始對象,作為對照
b是a的引用,和a指向同一個對象
c是a的一個淺拷貝,將a的內容拷貝過來了,就是和a平行的兩個對象了,但是裡面元素如果是對象,僅拷貝其引用,即a[4]變化後c[4]也對應變化了,因為他倆實際指向同一個對象,而a和c指向不同的對象
d則是從頭到尾全部拷貝過來,就連裡面的對象也拷貝了一份,因此a[4]變化而d[4]沒有變化,因為a[4]和d[4]在拷貝的時候值一樣,但是其實已經是兩個對象了。
下面是上面內容的輸出結果。
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c = [1, 2, 3, 4, ['a', 'b', 'c']]
d = [1, 2, 3, 4, ['a', 'b']]
Ⅸ Python的列表有沒有淺復制跟深復制的概念
有的。比如:
首先這里導入模塊,並生成三個列表
發現list2和list3有不同,其中list2就是淺復制,list3就是深復制
淺復制就是指當對象的欄位值被復制時,欄位引用的對象不會被復制,也就是引用的對象和原數據還是同一個,並沒有產生一個新的對象
深復制指對對象中欄位引用的對象也進行復制的一種方式,會產生一個新的值相同的不同對象