Python拷貝物件(淺拷貝copy與深拷貝deepcopy)
先說一段廢話。Python中的引數傳遞都是物件引用傳遞,這種方式相當於傳值和傳引用的一種綜合。如果函式收到的是一個可變物件(比如字典或者列表)的引用,就能修改物件的原始值——相當於通過“傳引用”來傳遞物件。如果函式收到的是一個不可變物件(比如數字、字元或者元組)的引用,就不能直接修改原始物件——相當於通過“傳值”來傳遞物件。
Python通過引用計數機制實現自動垃圾回收功能,Python中的每個物件都有一個引用計數,用來計數該物件在不同場所分別被引用了多少次。每當引用一次Python物件,相應的引用計數就增1,每當消毀一次Python物件,則相應的引用就減1,只有當引用計數為零時,才真正從記憶體中刪除Python物件。
Python提供了3種複製方法,最常見的=、copy.copy()、copy.deepcopy()。下面通過一段程式碼來看這三種複製方法的異同。
這裡定義了一個列表a,前面的元素的不可變型別的int,在最後append了一個可變型別dict(),然後打印出各個地方列表a和元素的id值。輸出結果如下:#!/usr/bin/python import copy def fun(list): print(id(list)) for li in list: print id(li), if __name__ == '__main__': a = [x for x in range(5)] a.append({'name':'zhangsan', 'age':20}) print id(a) for x in a: print id(x), print '' print '----------' fun(a) print '' print '----------' fun(copy.copy(a)) print '' print '----------' fun(copy.deepcopy(a)) print ''
列印出了各個物件的ID值,如果id一樣,毫無疑問就是同一個物件。當呼叫預設複製函式時,形參的id和實參的id是相同的(紅色框),也就是說的同一個物件,而呼叫copy模組拷貝時形參id和實參id不同,也就是說是不同的物件。注意觀察列表中的最後一個dict元素。預設的=複製和copy複製得到的id是相同的,也就是說他們是同一個物件,而deepcopy的id和其他都不一樣,也就是說是新物件。
再看一個程式碼:
最後輸出import copy #!/usr/bin/python #encoding=utf-8 a = [1, 2, 3, 4, ['a', 'b']] b = a c = copy.copy(a) d = copy.deepcopy(a) a.append(5) a[4].append('c') print 'a = ', a print 'b = ', b print 'c = ', c print 'd = ', d
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']]
所以說copy會對原物件拷貝,但不會遞迴深拷貝,而deepcopy是遞迴深拷貝的,這麼一來copy是介於=和deepcopy的,用的肯定不多。
1. copy.copy 淺拷貝 只拷貝父物件,不會拷貝物件的內部的子物件。
2. copy.deepcopy 深拷貝 拷貝物件及其子物件
相關推薦
Python拷貝物件(淺拷貝copy與深拷貝deepcopy)
先說一段廢話。Python中的引數傳遞都是物件引用傳遞,這種方式相當於傳值和傳引用的一種綜合。如果函式收到的是一個可變物件(比如字典或者列表)的引用,就能修改物件的原始值——相當於通過“傳引用”來傳遞
Python淺拷貝copy()與深拷貝deepcopy()區別
不同的 改變 變量 一個 元素 obj 存儲方式 port 同時 其實呢,淺拷貝copy()與深拷貝deepcopy()之間的區分必須要涉及到python對於數據的存儲方式。 首先直接上結論: —–我們尋常意義的復制就是深復制,即將被復制對象完全再復制一遍作為獨立的新個體
Python 淺拷貝copy()與深拷貝copy.deepcopy()
首先我在這介紹兩個新的小知識,要在下面用到。一個是函式 id() ,另一個是運算子 is。id() 函式就是返回物件的記憶體地址;is 是比較兩個變數的物件引用是否指向同一個物件,在這裡請不要和 == 混了,== 是比較兩個變數的值是否相等。 >>> a = [1,2,3] >
python變量及淺復制與深復制
python變量 深淺復制一、變量及定義: 變量定義:一段存放在內存特定區域的空間,在python中變量名沒有類型,引用的對象有類型之分; 命名規則:字母或下劃線開頭,不能以數字開頭。 特殊變量:以單下劃線(_)開頭的變量 不能被 from xxx import * 導入;即保護類型只
python初學一(while雙迴圈語句與典型的例題)
一、while 格式: 二、while 巢狀與例題: 1、while巢狀:
Python 淺拷貝與深拷貝,copy模組
python中的任何變數都是物件(引用型別)。 python中的變數分為可變型別和不可變型別。(淺拷貝和深拷貝都是拷貝可變型別內容,不可變型別不會拷貝) 注意:因為元組是不可變型別,所以元組的淺拷貝並不會拷貝任何內容,而是直接引用源元組(和=賦值等同)。 如果元組中的元
Python 列表淺拷貝與深拷貝
deep log es2017 .com com python 列表 imp http bsp 淺拷貝 shallow copy 和深拷貝 deep copy list.copy() 淺拷貝:復制此列表(只復制一層,不會復制深層對象) 等同於 L[:] 舉例: 淺拷貝:
python中的淺拷貝與深拷貝
post 相同 pre body python and aos deep light 淺拷貝可以拿丈夫與媳婦公用一張銀行卡來舉例 # python >>> husband = [‘liang‘,123,[10000,6000]] #丈夫的銀行卡信息
python copy與deepcopy (拷貝與深拷貝)
int clas 相同 pre 印象 不同的 copy 怎樣 結果 copy與deepcopy python 中的copy與deepcopy是內存數據的操作,但是兩個函數有一定的區別。 1.copy import copy list = [1, [4, 5, 6], 2,
python 淺拷貝與深拷貝
python 變量 淺拷貝 深拷貝 python變量在內存中是這樣存儲的: 在python中,一切都是對象,對象的存儲是引用存儲,存儲的只是變量的值所在的內存地址,而不是這個變量的值本身。 如果對值進行修改,其實是在內存中新創建一個值,把變量指向這個值的地址可以看出地址發生了改變如果是兩個值相
OpenCV中影象的淺拷貝與深拷貝 = copy clone區別
下面介紹三種OpenCV複製影象的方法: 方法1、過載運算子= 使用過載運算子“=”進行的拷貝是一種淺拷貝,雖然它們有不同的矩陣頭,但是二者共享相同的記憶體空間,二者內容相互關聯,任何一個變數變化的同時另一個變數也隨之改變。 /*OpenCV v1版本*/ IplImage im
Python中賦值、淺拷貝與深拷貝的區別
賦值,其實就是物件的引用,對新物件的如何修改都會影響到原始物件。 Python中有兩種拷貝操作:淺拷貝和深拷貝。 copy.copy(x):返回x的淺拷貝。 copy.deepcopy(x):返回x的深拷貝。 那麼都是拷貝,淺拷貝和深拷貝有什麼不同嗎? 淺
Python - 淺拷貝與深拷貝 - 再次整理
# -*- coding: UTF-8 -*- import copy def print_id(lst): lst_id = [id(y) for y in lst] lst_id.extend([id(y) for y in lst[1]]) return
Python中的複製、淺拷貝與深拷貝
1.物件的三要素 id、type以及value,id唯一標識一個物件,相當於地址,id一樣,說明就是同一個東西。type和value就是字面意思。 2.==和is ==比較的是value,is比較的是id,意思是 “是否為同一個物件”,條件比==要嚴格。 3.可變物
Python —— 淺拷貝 、仿深拷貝 與 深拷貝
(1)淺拷貝:同一個記憶體地址,擁有不同的變數名稱。(兩個變數不管更改哪一個,更改的第幾層,只要有一個變,就都變) (2)深拷貝:初始資料一致,記憶體地址不一致(兩者相互獨立,更改哪一個,或哪一個的哪一層,都與另一個無關) (3)仿深拷貝(第一層建立的是新的記憶體。從第二層開始,
Python學習之淺拷貝與深拷貝
1. 淺拷貝 淺拷貝只複製父物件,其內部的子物件不復制。可通過copy.copy實現。 2. 深拷貝 深拷貝不僅複製父物件,還複製子物件,相當於重新生成了一個一模一樣的物件。 3. 區別 import copy a = [1, 2, 3] b = a c = co
python列表的複製,扯一下淺拷貝與深拷貝的區別
將一個列表的資料複製到另一個列表中。使用列表[:],可以呼叫copy模組 import copy A = [21,22,23,24,['a','b','c','d'],25,26] B = A #直接賦值 C = A[:]
js中值的基本型別與引用型別,以及物件引用,物件的淺拷貝與深拷貝
js有兩種型別的值:棧:原始資料型別(undefinen,null,boolead,number,string)堆:引用資料型別(物件,函式和陣列)兩種型別的區別是:儲存位置不同,原始資料型別直接儲存在棧(stack)中的簡單資料段,佔據空間小,大小固定,屬於被頻繁使用的資料,所以放入棧中儲存;引用資料型別儲
C++淺拷貝與深拷貝(程式設計師面試寶典試題)
#include<iostream> #include<cstdlib> #include<vector> #include<cstring> using namespace std; class CDemo{ publi
python幾個面試題目:單例模式,淺拷貝與深拷貝
主要參考git上一篇面試題目,連結如下https://github.com/taizilongxu/interview_python#2-python%E4%B8%AD%E7%9A%84%E5%85%83%E7%B1%BBmetaclass 實現單例模式,對每種方式新增更詳