一步一步帶你理解 Python 中的淺複製與深複製

2021-01-10 開發小凱

Python 中的賦值語句不會對對象進行拷貝,僅僅是將變量名指向對象。對於不可修改的對象來說,這種機制不會影響我們日常的使用。但是,對於可修改的對象,你偶爾可能需要對該對象做一個真正的複製。何為真正的複製?就是修改拷貝來的對象不會影響原來的對象。

Python 中內置的可修改的集合類對象,比如列表、字典、集合等,可以直接使用對應的工廠方法進行拷貝。

需要注意的是,對於複合類型的對象,比如列表、字典、集合等,複製有淺複製與深複製兩種類型。

淺複製意味著新建一個對象,但是其子元素仍然指向的對應原對象的子對象。也就是說,這只會對原對象進行一層的拷貝,而不會遞歸的對子對象也進行拷貝。

深複製則會遞歸的對子對象進行拷貝。

如果上面的看不懂,沒關係,我們通過一個個例子來搞清楚。

淺複製

現在下面這個列表,我們使用 list() 方法對它進行複製

這意味著 xs 和 ys 是兩個不同的對象。我們可以看看它們的值

為了證明 xs 與 ys 確實不同,我們可以做個小實驗。添加一個子列表到 xs 中,然後看會不會影響 ys 。

與預期相同,如果只是修改原對象這一層,確實不對對 ys 造成影響。

但是由於是淺複製,ys 中的子元素並非是 xs 子元素的拷貝,僅僅是 xs 子對象的引用。因此,如果你修改 xs 中的子元素,ys 中的子元素同樣會被修改。

看起來我們只是修改了 xs 中的子元素,實則 ys 中的子元素也被修改了,這是由於淺複製的緣故。

現在我們大概清楚了淺複製與深複製的區別,但是還有兩個問題待解決:

一是,對於內置的集合類對象,我們怎麼進行深複製?

二是,對於任意的類,又該如何進行淺複製與深複製?

答案是標準庫中的 copy 模塊,其提供了簡單的方法對對象進行淺複製或深複製。

深複製

這次我們仍然使用上面的例子,不同的是,我們使用 copy 模塊中的 deepcopy() 方法來進行複製。

還是先看看各自的值

這次,因為 zs 對 xs 進行了深複製,即不僅拷貝了 xs 本身,還對它的子對象都進行了遞歸的拷貝,所以,如果我們再次修改 xs 的子元素時,並不會對 zs 造成影響。我們來試一試

果然,與預期一致。

順便說下,使用 copy 模塊中的 copy() 方法可以對對象進行淺複製。平時開發需要淺複製的時候,你可以使用該方法,但如果碰到內置的集合類對象,比如列表、字典、集合等的時候,使用對應的工廠方法如 list() ,dict() ,set() 等更 Pythonic 一些。

對任意對象進行複製

現在有一個點類 Point ,如下

其中,__repr__ 方法可以讓我們更方便的查看對象的信息。需要注意的是,f'...' 這種格式化字符串的方式在 Python 3.6 才支持,如果是 Python 2 或者 3.6 以前的版本可以使用 '...' % (v1[, v2, ...]) 的方式。

現在我們創建一個點對象並進行淺複製

查看兩個對象的信息

和預期一致。

需要注意的是,因為類的兩個成員 x 和 y 都是簡單類型,這裡是整型,所以這裡淺複製與深複製沒有任何差別。後面我會擴展這個例子。

現在我要定義一個矩形類,其類成員將會使用到上面的點類。

首先我們先試一下淺複製

看下各自的信息

記得我們上面修改列表的淺複製與深複製的例子嗎?這裡,我要類似的實驗。我們修改 rect 的成員,不出意外的話,srect 也會改變。

果然。

下面,我會進行深複製,然後再類似的修改

這次,深複製出來的 drect 對象與 srect 才能說是「真正不同」的對象。

copy 模塊中還有其它很多用法,比如定義對象的 __copy__() 和 __deepcopy__() 方法可以自定義對象的淺複製與深複製行為等。這不是本文的重心,有興趣的可以去看相應的文檔 https://docs.python.org/3/library/copy.html 。

小結

* 淺複製不會克隆子對象,所以,複製出來的對象和原對象並非完全不想關。

* 深複製會遞歸的克隆子對象,所以,複製出來的對象和原對象完全不相關,但是深複製比淺複製會慢一些。

* 使用 copy 模塊你可以複製任何類,不管是淺複製還是深複製。

鞏固

從網上找了組圖片(侵刪),讓大家加深下認識

首先是賦值

然後是淺複製

最後是深複製

相關焦點

  • Python 拓展之詳解深拷貝和淺拷貝
    其實單從表面意思來說,copy 就是將某件東西再複製一份,但是在很多程式語言中,比如 Python,C++中,它就不是那麼的簡單了。>>> a = 1>>> b = a>>> b1看到上面的例子,從表面上看我們似乎是得到了兩個 1,但是如果你看過我之前寫的文章,你應該對一句話有印象,那就是 「變量無類型」, Python 中變量就是一個標籤,這裡我們有請 id() 閃亮登場,看看它們在內存中的位置。
  • Python實驗課:字典數據的複製與遍歷
    Python提供了兩種方式來複製字典:一種方式是淺複製方式;一種方式是深複製方式。我們先來看淺複製方式,淺複製只是把當前字典內的列表、元組等可迭代對象的引用複製給新字典,當原字典的可迭代對象內容改變時,新字典的可迭代對象內容也會改變。字典對象的copy()方法可以淺複製一個字典數據。
  • 奇妙的Python編程之旅:字符串拼接,格式化輸出和深淺複製
    我們在學習深淺複製的時候,需要引入一個模塊impot copy.L淺複製=L2.copy()輸出L淺複製的結果為[1,['a','b']]L深複製=copy.deepcopy(L2)輸出L深複製的結果為[1,['a','b']],深複製和淺複製的輸出結果類似,怎麼樣才能讓兩個值有所區別呢?
  • Python中又一對有趣的功能:淺拷貝與深拷貝
    先把淺拷貝與深拷貝的概念拋出來:淺拷貝:不考貝子對象的內容,只拷貝子對象的引用。調用Python內置函數copy(源對象)。深拷貝:子對象的內存也會被拷貝一份,並且對子對象的修改不會影響源對象。調用Python內置函數deepcopy(源對象)。
  • Python數據類型串講(中)
    2、列表在對序列有了大體的認識後,現在開始介紹序列中最具代表性的數據類型——列表。python中列表以中括號'[ ]'為標識,將一個或多個元素(以逗號分隔)括起來為一個列表,其元素可以為python中任意一種數據類型包括列表本身,且各元素不需要具備相同的數據類型。
  • CAD入門必備(一)移動和複製快速掌握
    而我們在使用CAD中,用得最頻繁的功能就是移動和複製了,當然這也是新手必備的其中一項最簡單的功能,今天就一起來學習一下吧。一、移動:分為快捷鍵m移動和快捷鍵o偏移就是將選定的圖形從一個位置移動到新的位置。移動圖形時需要確定的就是圖形移動的方向和距離。
  • 「黑技能」——python檢測u盤並「偷偷」複製內容!
    這兩天在網上又發現python一個比較好玩的庫psutil,它是用來輕鬆獲取系統運行的進程和系統利用率,包括CPU、內存、磁碟、網絡等信息。也就是說用它來獲取硬體狀態信息的唄!然後一個「邪念」浮出腦海——打槍的不要,「偷偷」拷貝別人U盤內容!
  • Python 深拷貝、淺拷貝
    淺拷貝淺拷貝是對於一個對象的頂層拷貝通俗的理解是:拷貝了引用,並沒有拷貝內容2. 深拷貝深拷貝是對於一個對象所有層次的拷貝(遞歸)進一步理解深拷貝3. 拷貝的其他方式分片表達式可以賦值一個序列字典的copy方法可以拷貝一個字典4.
  • RNA如何複製?
    RNA複製酶(RdRp)即「RNA依賴的RNA聚合酶(RdRp)」RNA聚合酶的一種,存在於大部分RNA病毒中。
  • 用Python複製文件的9個方法
    Python 中有許多「開蓋即食」的模塊(比如 os,subprocess 和 shutil)以支持文件 I/O 操作。在這篇文章中,你將會看到一些用 Python 實現文件複製的特殊方法。下面我們開始學習這九種不同的方法來實現 Python 複製文件操作。在開始之前,你必須明白為什麼了解最適合你的 Python 複製文件方法是如此重要。
  • MCB:癌細胞DNA的連續複製或引發複製叉的崩潰
    2012年11月21日 訊 /生物谷BIOON/ --近日,刊登在國際雜誌Molecular & Cellular Biology上的一篇研究報告中,來自南加州大學的研究者表示,發生特定突變的細胞可以繼續進行其DNA的複製,即便是抗癌療法移除了它們進行增殖的原材料,它們也可以依然增殖,這就引發了一系列災難性的結果發生。
  • 生物學DNA複製與細胞分裂的過程=猜想中的宇宙空間複製的過程?
    對於宇宙可以複製的假說,相信看了我發的前兩篇文章,想必你也已經明白宇宙無限循環複製大致是怎麼一回事了。這樣的假說猜想論,或許可以揭示出新的出乎意料的驚人的宇宙空間複製可能性,讓以前人類的一些觀點看起來有了新的認識和可能。
  • 你複製是原創,我複製是抄襲?
    [摘要]只要藝術家有新穎的理念,即使作品被無限複製,他的原創性也毋庸置疑。他複製是創作,你複製是抄襲「挪用主義」倡導對現成品的重組和轉換,或者說,對已知現實的「再創造」。故事開始於美國超市常見的清潔球品牌布裡洛(Brillo)。1964年,安迪·沃霍爾仿製了一批布裡洛紙箱,成為波普藝術的經典之作,被收藏於各國美術館。然而2007年,斯德哥爾摩當代美術館宣稱,館藏的大量布裡洛紙箱並非原作,而是前任館長龐圖·胡爾騰1990年代仿造的贗品。
  • 這個世界中沒有什麼是可以被複製的,複製人又該如何生存
    這個世界中沒有什麼是可以被複製的,複製人又該如何生存可以說很難描述看完《銀翼殺手》這部電影是什麼樣的感受,和以前相比總感覺少了一切什麼,不知是拓展性的內涵還是看電影的感覺,但也完美的延續著電影帶給我們的某種魅力,並且補足了太多因生活而給我們帶來的遺憾
  • 如何理解細胞質基因的半自主自我複製?
    線粒體和葉綠體中的DNA,能夠進行半自主自我複製,並通過轉錄和翻譯合成蛋白質
  • 首次合成可無限複製的RNA
    美國斯克裡普斯研究所科學家的新發現,在回答生命如何開始的生化問題上邁出了重要一步,他們首次在無須任何蛋白質和其他細胞成分的情況下,合成出可自我複製的RNA,而且這種複製可無限進行下去。
  • 高性能Mysql主從架構的複製原理及配置詳解
    當一個從伺服器連接主伺服器時,它通知主伺服器從伺服器在日誌中讀取的最後一次成功更新的位置。從伺服器接收從那時起發生的任何更新,然後封鎖並等待主伺服器通知新的更新。請注意當你進行複製時,所有對複製中的表的更新必須在主伺服器上進行。否則,你必須要小心,以避免用戶對主伺服器上的表進行的更新與對從伺服器上的表所進行的更新之間的衝突。
  • 高中生物說課稿:《DNA的複製》
    一、 說教材1.教材地位和作用 《DNA的複製》這一部分內容也是第三章的重點內容之一。它既是對前面已學習的孟德爾遺傳定律和減數分裂知識進一步的深化理解,也是整個遺傳的基礎。 2.教學目標(1)知識目標:概述DNA分子的複製;探討DNA複製的生物學意義(2)能力目標:培養學生自學能力,觀察能力、分析理解能力(3)德育目標:激發學生學科學、用科學、愛科學的求知慾3.教學重點、難點(1)教學重點:DNA複製的條件、過程及特點。
  • 新型冠狀病毒會在買來的肉產品中不斷複製嗎?
    目前,新型冠狀病毒引發的肺炎正嚴重影響著人們的生活,各種擔心也在人群中像病毒一樣擴散著。比如有的人擔心家養的貓、狗會不會也被新型冠狀病毒感染患病?從市場上買來的豬肉會不會也成為病毒複製的溫床?至於買來的豬牛羊肉會不會成為病毒複製的溫床,那是絕對不可能。就算新型冠狀病毒能夠感染某種動物,當那種動物失去生命後,病毒剩下的也只是哀嚎。病毒不是細菌,一塊肉在戶外放幾天就會腐敗,這是由於那塊肉染上了細菌,細菌在肉上大量繁殖並將肉分解的緣故。而病毒沒有細胞結構,它自己也無法繁殖,只能寄生在宿主的細胞中,藉助宿主的設備複製自己。
  • DNA分子的複製學習
    DNA分子的複製【學習目標】1、理解證明DNA分子是半保留複製的方法和過程2、概述DNA分子複製的過程及特點3、探討DNA複製的生物學意義分析實驗現象要點詮釋:(1)在氮源為14N的培養基上生長的大腸桿菌,其DNA分子均為14N-DNA,在離心管中離心形成的帶位於上層,稱為輕帶。