欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python中copy()與deepcopy()的區(qū)別小結

 更新時間:2018年08月03日 10:54:06   作者:J_pyc  
接觸python有一段時間了,一直沒有系統(tǒng)的學習過,也對copy,deepcoy傻傻的分不清,故抽出時間來理一下。 下面這篇文章主要給大家介紹了關于python中copy()與deepcopy()的區(qū)別的相關資料,需要的朋友可以參考下

前言

copy()與deepcopy()之間的區(qū)分必須要涉及到python對于數據的存儲方式。

深復制被復制對象完全再復制一遍作為獨立的新個體單獨存在。所以改變原有被復制對象不會對已經復制出來的新對象產生影響。

淺復制并不會產生一個獨立的對象單獨存在,他只是將原有的數據塊打上一個新標簽,所以當其中一個標簽被改變的時候,數據塊就會發(fā)生變化,另一個標簽也會隨之改變。

import copy
 origin = [1, 2, [3, 4]]
#origin 里邊有三個元素:1, 2,[3, 4]
cop1 = copy.copy(origin)
cop2 = copy.deepcopy(origin)
cop1 == cop2
------>True
 cop1 is cop2
------>False 
#cop1 和 cop2 看上去相同,但已不再是同一個object
 origin[2][0] = "hey!" 
 origin
------>[1, 2, ['hey!', 4]]
 cop1
------>[1, 2, ['hey!', 4]]
 cop2
------>[1, 2, [3, 4]]

可以看到 cop1,也就是 copy 跟著 origin 改變了。而 cop2 ,也就是 deep copy 并沒有變。

Python存儲方式

Python 存儲變量的方法跟其他 OOP 語言不同。它與其說是把值賦給變量,不如說是給變量建立了一個到具體值的 reference。

當在 Python 中 a = something 應該理解為給 something 貼上了一個標簽 a。當再賦值給 a 的時候,就好象把 a 這個標簽從原來的 something 上拿下來,貼到其他對象上,建立新的 reference。 這就解釋了一些 Python 中可能遇到的詭異情況:

>> a = [1, 2, 3]
>>> b = a
>>> a = [4, 5, 6] //賦新的值給 a
>>> a
[4, 5, 6]
>>> b
[1, 2, 3]
# a 的值改變后,b 并沒有隨著 a 變

>>> a = [1, 2, 3]
>>> b = a
>>> a[0], a[1], a[2] = 4, 5, 6 //改變原來 list 中的元素
>>> a
[4, 5, 6]
>>> b
[4, 5, 6]
# a 的值改變后,b 隨著 a 變了

上面兩段代碼中,a 的值都發(fā)生了變化。區(qū)別在于,第一段代碼中是直接賦給了 a 新的值(從 [1, 2, 3] 變?yōu)?[4, 5, 6]);而第二段則是把 list 中每個元素分別改變。

而對 b 的影響則是不同的,一個沒有讓 b 的值發(fā)生改變,另一個變了。怎么用上邊的道理來解釋這個詭異的不同呢?

首次把 [1, 2, 3] 看成一個物品。a = [1, 2, 3] 就相當于給這個物品上貼上 a 這個標簽。而 b = a 就是給這個物品又貼上了一個 b 的標簽。


第一種情況:

a = [4, 5, 6] 就相當于把 a 標簽從 [1 ,2, 3] 上撕下來,貼到了 [4, 5, 6] 上。

在這個過程中,[1, 2, 3] 這個物品并沒有消失。 b 自始至終都好好的貼在 [1, 2, 3] 上,既然這個 reference 也沒有改變過。 b 的值自然不變。

第二種情況:

a[0], a[1], a[2] = 4, 5, 6 則是直接改變了 [1, 2, 3] 這個物品本身。把它內部的每一部分都重新改裝了一下。內部改裝完畢后,[1, 2, 3] 本身變成了 [4, 5, 6]。

而在此過程當中,a 和 b 都沒有動,他們還貼在那個物品上。因此自然 a b 的值都變成了 [4, 5, 6]。

搞明白這個之后就要問了,對于一個復雜對象的淺copy,在copy的時候到底發(fā)生了什么?
再看一段代碼:

>>> import copy
>>> origin = [1, 2, [3, 4]]
#origin 里邊有三個元素:1, 2,[3, 4]
>>> cop1 = copy.copy(origin)
>>> cop2 = copy.deepcopy(origin)
>>> cop1 == cop2
True
>>> cop1 is cop2
False 
#cop1 和 cop2 看上去相同,但已不再是同一個object
>>> origin[2][0] = "hey!" 
>>> origin
[1, 2, ['hey!', 4]]
>>> cop1
[1, 2, ['hey!', 4]]
>>> cop2
[1, 2, [3, 4]]
#把origin內的子list [3, 4] 改掉了一個元素,觀察 cop1 和 cop2

學過docker的人應該對鏡像這個概念不陌生,我們可以把鏡像的概念套用在copy上面。

概念圖如下:

copy對于一個復雜對象的子對象并不會完全復制,什么是復雜對象的子對象呢?就比如序列里的嵌套序列,字典里的嵌套序列等都是復雜對象的子對象。對于子對象,python會把它當作一個公共鏡像存儲起來,所有對他的復制都被當成一個引用,所以說當其中一個引用將鏡像改變了之后另一個引用使用鏡像的時候鏡像已經被改變了。

所以說看這里的origin[2],也就是 [3, 4] 這個 list。根據 shallow copy 的定義,在 cop1[2] 指向的是同一個 list [3, 4]。那么,如果這里我們改變了這個 list,就會導致 origin 和 cop1 同時改變。這就是為什么上邊 origin[2][0] = “hey!” 之后,cop1 也隨之變成了 [1, 2, [‘hey!', 4]]。

而deepcopy概念圖如下:

deepcopy的時候會將復雜對象的每一層復制一個單獨的個體出來。

這時候的 origin[2] 和 cop2[2] 雖然值都等于 [3, 4],但已經不是同一個 list了。即我們尋常意義上的復制。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • python簡單線程和協程學習心得(分享)

    python簡單線程和協程學習心得(分享)

    下面小編就為大家?guī)硪黄猵ython簡單線程和協程學習心得(分享)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • PyQt5-QDateEdit的簡單使用操作

    PyQt5-QDateEdit的簡單使用操作

    這篇文章主要介紹了PyQt5-QDateEdit的簡單使用操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • pytorch AvgPool2d函數使用詳解

    pytorch AvgPool2d函數使用詳解

    今天小編就為大家分享一篇pytorch AvgPool2d函數使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • Anaconda下Python中GDAL模塊的下載與安裝過程

    Anaconda下Python中GDAL模塊的下載與安裝過程

    這篇文章主要介紹了Anaconda下Python中GDAL模塊的下載與安裝方法,本文介紹在Anaconda環(huán)境下,安裝Python中柵格、矢量等地理數據處理庫GDAL的方法,需要的朋友可以參考下
    2023-04-04
  • Tornado Web服務器多進程啟動的2個方法

    Tornado Web服務器多進程啟動的2個方法

    這篇文章主要介紹了Tornado Web服務器多進程啟動的2個方法,Tornado是一個用Ptyhon寫的WEB服務器,需要的朋友可以參考下
    2014-08-08
  • Python OpenCV 圖像矯正的原理實現

    Python OpenCV 圖像矯正的原理實現

    這篇文章主要介紹了Python OpenCV 圖像矯正的原理實現,檢測邊緣點;以邊緣點作為輸入,采用Hough直線檢測,檢測出最多點共線的四條直線,更多相關內容需要的朋友可以參考一下
    2022-07-07
  • 詳解python函數的閉包問題(內部函數與外部函數詳述)

    詳解python函數的閉包問題(內部函數與外部函數詳述)

    這篇文章主要介紹了python函數的閉包問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • Python使用內置函數setattr設置對象的屬性值

    Python使用內置函數setattr設置對象的屬性值

    這篇文章主要介紹了Python使用內置函數setattr設置對象的屬性值,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • python 調用js的四種方式

    python 調用js的四種方式

    這篇文章主要介紹了python 調用js的四種方式,幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下
    2021-04-04
  • TensorBoard 計算圖的可視化實現

    TensorBoard 計算圖的可視化實現

    今天小編就為大家分享一篇TensorBoard 計算圖的可視化實現,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02

最新評論