淺拷貝python
Ⅰ python深拷貝和淺拷貝的區別
淺拷貝是對一個對象父級(外層)的拷貝,並不會拷貝子級(內部),而深拷貝對一個對象是所有層次的拷貝(遞歸),內部和外部都會被拷貝過來。
使用淺拷貝的時候,分為兩種情況。
第一種,如果最外層的數據類型是可變的,比如說列表,字典等,淺拷貝會開啟新的地址空間去存放。
Ⅱ python的復制,深拷貝和淺拷貝的區別
在Python中存在深拷貝與淺拷貝的區別,相信有些Python初學者可能就有些疑惑,是指什麼意思呢?
1. 賦值其實只是傳遞對象引用,引用對象id是一樣的。
2. 淺拷貝是指拷貝的只是原始對象元素的引用,換句話說,淺拷貝產生的對象本身是新的,但是它的內容不是新的,只是對原對象的一個引用。
3. 深拷貝是指完全拷貝原始對象,而且產生的對象是新的,並且不受其他引用對象的操作影響。
Ⅲ 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中的賦值,淺拷貝和深拷貝的區別
賦值(=),就是創建了對象的一個新的引用,修改其中任意一個變數都會影響到另一個。
淺拷貝:創建一個新的對象,但它包含的是對原始對象中包含項的引用(如果用引用的方式修改其中一個對象,另外一個也會修改改變){1,完全切片方法;2,工廠函數,如list();3,模塊的()函數}
深拷貝:創建一個新的對象,並且遞歸的復制它所包含的對象(修改其中一個,另外一個不會改變){模塊的deep.deep()函數}
Ⅳ Python3 & 淺拷貝與深拷貝
在Python中對象的賦值(=)其實就是對象的引用。即:當創建一個對象,把它賦值給另一個變數時,python並沒有拷貝這個對象,只是拷貝了這個對象的引用而已。
Python中對象的拷貝分為:淺拷貝()和深拷貝(deep)。
淺拷貝:拷貝了最外圍的對象本身,內部的元素都只是拷貝了一個引用而已。也就是,將原對象在內存中引用地址拷貝過來,然後讓新的對象指向這個地址。可以使用「=」或列表自帶的()函數(如list.()),或使用模塊的()函數。
深拷貝:外圍和內部元素都進行了拷貝對象本身,而不是引用。即把對象復制一遍,並且該對象中引用的其他對象也同時復制,完全得到一個新的一模一樣的對象,對新對象里的值進行修改不會影響原有對象,新對象和原對象完全分離開。深拷貝只能使用模塊中deep()函數,使用前要導入:from import deep。
Python中對象分為不可變對象 、可變對象。
不可變對象:一旦創建就不可修改的對象,例如:字元串、元組、數字
可變對象:可以修改的對象,例如:列表、字典。
其中Python中的切片可以應用於:列表、元組、字元串,但不能應用於字典。
而深淺拷貝,可應用於序列(列表、元組、字元串),也可應用於字典。
其中不可變對象,不管是深拷貝還是淺拷貝,地址值在拷貝後的值都是一樣的。
以下以元組(不可變類型)為例
從上述示例可以看出:
不可變對象類型,沒有被拷貝的說法,即便是用深拷貝,查看id的話也是一樣的,如果對其重新賦值,也只是新創建一個對象,替換掉舊的而已。
所以不可變類型,不管是深拷貝還是淺拷貝,地址值和拷貝後的值都是一樣的。
以下以列表(可變類型)為例
第一種方法:使用=號淺拷貝
輸出結果:
第二種方法:使用淺拷貝
輸出結果:
第三種方法:使用deep深拷貝
輸出結果:
從上述示例可以看出:
=淺拷貝:值相等,地址相等
淺拷貝:值相等,地址不相等
deep深拷貝:值相等,地址不相等
總結:
1,深淺拷貝都是對源對象的復制,佔用不同的內存空間。
2,不可變類型的對象,對於深淺拷貝毫無影響,最終的地址值和值都是相等的。
3,可變類型的對象,使用=淺拷貝時, 值相等,地址相等,對新對象里的值進行修改同時會影響原有對象;使用淺拷貝時值相等,地址不相等;使用deep深拷貝時值相等,地址不相等。可以看出針對可變類型淺拷貝和deep深拷貝,對新對象里的值進行修改不會影響原有對象。
Ⅵ 什麼是深拷貝和淺拷貝
淺拷貝就是指對象復制的時候只復制一層;深拷貝是指復制對象的所有層級。
深拷貝和淺拷貝,主要是對象發生復制的時候,根據復制的層級不同來區分的。很多人在這里經常變數賦值發生混淆。對於JavaScript數組等復雜的數據類型來說,將其賦值給其它變數,其實只是復制了對象的地址給它,兩個變數指向的是同一個對象,因此普通的賦值既不是深拷貝也不是淺拷貝。
深拷貝和淺拷貝需要注意的地方就是可變元素的拷貝:
在淺拷貝時,拷貝出來的新對象的地址和原對象是不一樣的,但是新對象裡面的可變元素(如列表)的地址和原對象里的可變元素的地址是相同的,也就是說淺拷貝它拷貝的是淺層次的數據結構(不可變元素),對象里的可變元素作為深層次的數據結構並沒有被拷貝到新地址裡面去。
而是和原對象里的可變元素指向同一個地址,所以在新對象或原對象里對這個可變元素做修改時,兩個對象是同時改變的,但是深拷貝不會這樣,這個是淺拷貝相對於深拷貝最根本的區別。
Ⅶ python深拷貝和淺拷貝的區別
1、淺拷貝(shallow )
所謂「淺拷貝」,是指創建一個新的對象,其內容是原對象中元素的引用。(拷貝組合對象,不拷貝子對象)
常見的淺拷貝有:切片操作、工廠函數、對象的()方法、模塊中的函數。
2、深拷貝(deep )
所謂「深拷貝」,是指創建一個新的對象,然後遞歸的拷貝原對象所包含的子對象。深拷貝出來的對象與原對象沒有任何關聯。
深拷貝只有一種方式:模塊中的deep函數。
總結:
淺拷貝,沒有拷貝子對象,所以原始數據改變,子對象會改變
深拷貝,包含對象裡面的自對象的拷貝,所以原始對象的改變不會造成深拷貝里任何子元素的改變