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

Python?copy()與deepcopy()方法之間有什么區(qū)別

 更新時間:2022年10月12日 17:14:18   作者:Python熱愛者  
這篇文章主要介紹了Python中的copy()和deepcopy(),下面詳細介紹該內容并附上詳細代碼,需要的朋友可以參考一下文章的具體內容,希望對你有所幫助

前言

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

首先直接上結論:

  • 我們尋常意義的復制就是深復制,即將被復制對象完全再復制一遍作為獨立的新個體單獨存在。所以改變原有被復制對象不會對已經(jīng)復制出來的新對象產(chǎn)生影響。
  • 而淺復制并不會產(chǎn)生一個獨立的對象單獨存在,他只是將原有的數(shù)據(jù)塊打上一個新標簽,所以當其中一個標簽被改變的時候,數(shù)據(jù)塊就會發(fā)生變化,另一個標簽也會隨之改變。這就和我們尋常意義上的復制有所不同了。

對于簡單的 object,用 shallow copy 和 deep copy 沒區(qū)別

復雜的 object, 如 list 中套著 list 的情況,shallow copy 中的 子list,并未從原 object 真的「獨立」出來。也就是說,如果你改變原 object 的子 list 中的一個元素,你的 copy 就會跟著一起變。這跟我們直覺上對「復制」的理解不同。

看不懂文字沒關系我們來看代碼:

>>> 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

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

似乎 deep copy 更加符合我們對「復制」的直覺定義: 一旦復制出來了,就應該是獨立的了。如果我們想要的是一個字面意義的「copy」,那就直接用 deep_copy 即可。

那么為什么會有 shallow copy 這樣的「假」 copy 存在呢? 這就是有意思的地方了。

python的數(shù)據(jù)存儲方式

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會把它當作一個公共鏡像存儲起來,所有對他的復制都被當成一個引用,所以說當其中一個引用將鏡像改變了之后另一個引用使用鏡像的時候鏡像已經(jīng)被改變了。

所以說看這里的origin[2],也就是[3, 4]這個 list。根據(jù) 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],但已經(jīng)不是同一個 list了。即我們尋常意義上的復制。

到此這篇關于Python copy()與deepcopy()方法之間有什么區(qū)別的文章就介紹到這了,更多相關Python copy()與deepcopy()內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • python如何將自己的包上傳到PyPi并可通過pip安裝的方法步驟

    python如何將自己的包上傳到PyPi并可通過pip安裝的方法步驟

    本文主要介紹了python如何將自己的包上傳到PyPi并可通過pip安裝的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • keras中模型訓練class_weight,sample_weight區(qū)別說明

    keras中模型訓練class_weight,sample_weight區(qū)別說明

    這篇文章主要介紹了keras中模型訓練class_weight,sample_weight區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • Python使用filetype精確判斷文件類型

    Python使用filetype精確判斷文件類型

    判斷文件類型在開發(fā)中非常常見的需求,怎樣才能準確的判斷文件類型呢?首先大家想到的是文件的后綴,但是非常遺憾的是這種方法是非常不靠譜的,因為文件的后綴是可以隨意更改的,而python中有個小插件可以實現(xiàn),下面我們就來詳細探討下
    2017-07-07
  • 詳解Python給照片換底色(藍底換紅底)

    詳解Python給照片換底色(藍底換紅底)

    這篇文章主要介紹了詳解Python給照片換底色(藍底換紅底),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • python 進程池的兩種不同實現(xiàn)方法示例

    python 進程池的兩種不同實現(xiàn)方法示例

    這篇文章主要為大家介紹了python 進程池的兩種不同實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • Python編程實現(xiàn)微信企業(yè)號文本消息推送功能示例

    Python編程實現(xiàn)微信企業(yè)號文本消息推送功能示例

    這篇文章主要介紹了Python編程實現(xiàn)微信企業(yè)號文本消息推送功能,結合實例形式分析了Python微信企業(yè)號文本消息推送接口的調用相關操作技巧,需要的朋友可以參考下
    2017-08-08
  • Python實現(xiàn)地圖可視化folium完整過程

    Python實現(xiàn)地圖可視化folium完整過程

    Folium是一個基于leaflet.js的Python地圖庫,其中,Leaflet是一個非常輕的前端地圖可視化庫,本文重點給大家介紹Python實現(xiàn)地圖可視化folium完整過程,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • 4種Python基于字段的不使用元類的ORM實現(xiàn)方法總結

    4種Python基于字段的不使用元類的ORM實現(xiàn)方法總結

    在 Python 中,ORM(Object-Relational Mapping)是一種將對象和數(shù)據(jù)庫之間的映射關系進行轉換的技術,本文為大家整理了4種不使用元類的簡單ORM實現(xiàn)方式,需要的可以參考下
    2023-12-12
  • python中__init__方法知識點詳解

    python中__init__方法知識點詳解

    Python中常會看到在很多類中都有一個__init__函數(shù),該函數(shù)有什么作用,又該如何使用呢,下面這篇文章主要給大家介紹了關于python中__init__知識點的相關資料,需要的朋友可以參考下
    2023-04-04
  • Python中函數(shù)相關的變量作用域

    Python中函數(shù)相關的變量作用域

    這篇文章主要介紹了Python中函數(shù)相關的變量作用域,變量的作用域是指程序代碼能夠訪問該變量的區(qū)域,如果超出該區(qū)域,在訪問時就會出現(xiàn)錯誤,需要的朋友可以參考下
    2023-08-08

最新評論