日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python怎么避免浅拷贝_深度解读Python深拷贝与浅拷贝问题

發布時間:2025/4/16 python 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python怎么避免浅拷贝_深度解读Python深拷贝与浅拷贝问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?Illustrations by Leon Tukker

?

作者:PayneLi,Python全家桶,主要講述數據挖掘、機器學習和深度學習領域的前沿技術,同時還會推薦一些行業最新論文、技術專家的經驗分享。

在平時工作中,經常涉及到數據的傳遞,在數據傳遞使用過程中,可能會發生數據被修改的問題。為了防止數據被修改,就需要在傳遞一個副本,即使副本被修改,也不會影響原數據的使用。為了生成這個副本,就產生了拷貝。今天就說一下Python中的深拷貝與淺拷貝的問題。

概念普及:對象、可變類型、引用

數據拷貝會涉及到Python中對象、可變類型、引用這3個概念,先來看看這幾個概念,只有明白了他們才能更好的理解深拷貝與淺拷貝到底是怎么一回事。

Python對象

在Python中,對對象有一種很通俗的說法,萬物皆對象。說的就是構造的任何數據類型都是一個對象,無論是數字,字符串,還是函數,甚至是模塊,Python都對當做對象處理。

所有Python對象都擁有三個屬性:身份、類型、值。

看一個簡單的例子:

In [1]: name = "laowang" # name對象
In [2]: id(name) ?# id:身份的唯一標識
Out[2]: 1698668550104
In [3]: type(name) # type:對象的類型,決定了該對象可以保存什么類型的值
Out[3]: str
In [4]: name ?# 對象的值,表示的數據
Out[4]: 'laowang'

可變與不可變對象

在Python中,按更新對象的方式,可以將對象分為2大類:可變對象與不可變對象。

  • 可變對象:? 列表、字典、集合

    所謂可變是指可變對象的值可變,身份是不變的。

  • 不可變對象:數字、字符串、元組

    不可變對象就是對象的身份和值都不可變。新創建的對象被關聯到原來的變量名,舊對象被丟棄,垃圾回收器會在適當的時機回收這些對象。

In [7]: var1 = "python"
In [8]: id(var1)
Out[8]: 1700782038408#由于var1是不可變的,重新創建了java對象,隨之id改變,舊對象python會在某個時刻被回收
In [9]: var1 = "java"
In [10]: id(var1)
Out[10]: 1700767578296

引用

在 Python 程序中,每個對象都會在內存中申請開辟一塊空間來保存該對象,該對象在內存中所在位置的地址被稱為引用。在開發程序時,所定義的變量名實際就對象的地址引用。

引用實際就是內存中的一個數字地址編號,在使用對象時,只要知道這個對象的地址,就可以操作這個對象,但是因為這個數字地址不方便在開發時使用和記憶,所以使用變量名的形式來代替對象的數字地址。 在 Python 中,變量就是地址的一種表示形式,并不開辟開辟存儲空間。

就像 IP 地址,在訪問網站時,實際都是通過 IP 地址來確定主機,而 IP 地址不方便記憶,所以使用域名來代替 IP 地址,在使用域名訪問網站時,域名被解析成 IP 地址來使用。

通過一個例子來說明變量和變量指向的引用就是一個東西

In [11]: age = 18
In [12]: id(age)
Out[12]: 1730306752
In [13]: id(18)
Out[13]: 1730306752

逐步深入:引用賦值

上邊已經明白,引用就是對象在內存中的數字地址編號,變量就是方便對引用的表示而出現的,變量指向的就是此引用。賦值的本質就是讓多個變量同時引用同一個對象的地址。 ?那么在對數據修改時會發生什么問題呢?

  • 不可變對象的引用賦值

    對不可變對象賦值,實際就是在內存中開辟一片空間指向新的對象,原不可變對象不會被修改。

    原理圖如下:

下面通過案例來理解一下:

a與b在內存中都是指向1的引用,所以a、b的引用是相同的

In [1]: a = 1
In [2]: b = a
In [3]: id(a)
Out[3]: 1730306496
In [4]: id(b)
Out[4]: 1730306496

現在再給a重新賦值,看看會發生什么變化?

從下面不難看出:當給a 賦新的對象時,將指向現在的引用,不在指向舊的對象引用。

In [1]: a = 1
In [2]: b = a
In [5]: a = 2
In [6]: id(a)
Out[6]: 1730306816
In [7]: id(b)
Out[7]: 1730306496

  • 可變對象的引用賦值

    可變對象保存的并不是真正的對象數據,而是對象的引用。當對可變對象進行賦值時,只是將可變對象中保存的引用指向了新的對象。

原理圖如下:

仍然通過一個實例來體會一下,可變對象引用賦值的過程。

當改變l1時,整個列表的引用會指新的對象,但是l1與l2都是指向保存的同一個列表的引用,所以引用地址不會變。

In [3]: l1 = [1, 2, 3]
In [4]: l2 = l1
In [5]: id(l1)
Out[5]: 1916633584008
In [6]: id(l2)
Out[6]: 1916633584008
In [7]: l1[0] = 11
In [8]: id(l1)
Out[8]: 1916633584008
In [9]: id(l2)
Out[9]: 1916633584008

主旨詳解:淺拷貝、深拷貝

經過前2部分的解讀,大家對對象的引用賦值應該有了一個清晰的認識了。

下面大家思考一個這樣的問題:Python中如何解決原始數據在函數傳遞之后不受影響了?

這個問題Python已經幫我們解決了,使用對象的拷貝或者深拷貝就可以愉快的解決了。

下面具體來看看Python中的淺拷貝與深拷貝是如何實現的。

  • 淺拷貝:

    為了解決函數傳遞后被修改的問題,就需要拷貝一份副本,將副本傳遞給函數使用,就算是副本被修改,也不會影響原始數據 。

不可變對象的拷貝

不可變對象只在修改的時候才會在內存中開辟新的空間, 而拷貝實際上是讓多個對象同時指向一個引用,和對象的賦值沒區別。

同樣的,通過一個實例來感受一下:不難看出,a與b指向相同的引用,不可變對象的拷貝就是對象賦值。

In [11]: import copy
In [12]: a = 10
In [13]: b = copy.copy(a)
In [14]: id(a)
Out[14]: 1730306496
In [15]: id(b)
Out[15]: 1730306496

可變對象的拷貝

對于不可變對象的拷貝,對象的引用并沒有發生變化,那么可變對象的拷貝會不會和不可變對象一樣了?我們接著往下看。

通過下面這個實例可以看出:可變對象的拷貝,會在內存中開辟一個新的空間來保存拷貝的數據。當再改變之前的對象時,對拷貝之后的對象沒有任何影響。

In [24]: import copy
In [25]: l1 = [1, 2, 3]
In [26]: l2 = copy.copy(l1)
In [27]: id(l1)
Out[27]: 1916631742088
In [28]: id(l2)
Out[28]: 1916636282952
In [29]: l1[0] = 11
In [30]: id(l1)
Out[30]: 1916631742088
In [31]: id(l2)
Out[31]: 1916636282952

原理圖如下:

現在再回到剛才那個問題,是不是淺拷貝就可以解決原始數據在函數傳遞之后不變的問題了?下面看一個稍微復雜一點的數據結構。

通過下面這個實例可以發現:復雜對象在拷貝時,并沒有解決數據在傳遞之后,數據改變的問題。?出現這種原因,是copy() 函數在拷貝對象時,只是將指定對象中的所有引用拷貝了一份,如果這些引用當中包含了一個可變對象的話,那么數據還是會被改變。 這種拷貝方式,稱為淺拷貝。

In [35]: a = [1, 2]
In [36]: l1 = [3, 4, a]
In [37]: l2 = copy.copy(l1)
In [38]: id(l1)
Out[38]: 1916631704520
In [39]: id(l2)
Out[39]: 1916631713736
In [40]: a[0] = 11
In [41]: id(l1)
Out[41]: 1916631704520
In [42]: id(l2)
Out[42]: 1916631713736
In [43]: l1
Out[43]: [3, 4, [11, 2]]
In [44]: l2
Out[44]: [3, 4, [11, 2]]

原理圖如下:

對于上邊這種狀況,Python還提供了另一種拷貝方式(深拷貝)來解決。

  • 深拷貝

    區別于淺拷貝只拷貝頂層引用,深拷貝會逐層進行拷貝,直到拷貝的所有引用都是不可變引用為止。

接下來我們看看,要是將上邊的拷貝實例用使用深拷貝的話,原始數據改變的問題還會不會存在了?

下面的實例清楚的告訴我們:之前的問題就可以完美解決了。

import copy
l1 = [3, 4, a]
In [47]: l2 = copy.deepcopy(li)
In [48]: id(l1)
Out[48]: 1916632194312
In [49]: id(l2)
Out[49]: 1916634281416
In [50]: a[0] = 11
In [51]: id(l1)
Out[51]: 1916632194312
In [52]: id(l2)
Out[52]: 1916634281416
In [54]: l1
Out[54]: [3, 4, [11, 2]]
In [55]: l2
Out[55]: [1, 2, 3]

原理圖如下:

查漏補缺

為什么Python默認的拷貝方式是淺拷貝?

  • 時間角度:淺拷貝花費時間更少

  • 空間角度:淺拷貝花費內存更少

  • 效率角度:淺拷貝只拷貝頂層數據,一般情況下比深拷貝效率高。

本文知識點總結:

  • 不可變對象在賦值時會開辟新空間

  • 可變對象在賦值時,修改一個的值,另一個也會發生改變

  • 深、淺拷貝對不可變對象拷貝時,不開辟新空間,相當于賦值操作

  • 淺拷貝在拷貝時,只拷貝第一層中的引用,如果元素是可變對象,并且被修改,那么拷貝的對象也會發生變化

  • 深拷貝在拷貝時,會逐層進行拷貝,直到所有的引用都是不可變對象為止。

  • Python 中有多種方式實現淺拷貝,copy模塊的copy 函數 ,對象的 copy 函數 ,工廠方法,切片等。

  • 大多數情況下,編寫程序時,都是使用淺拷貝,除非有特定的需求

  • 淺拷貝的優點:拷貝速度快,占用空間少,拷貝效率高

最 近 熱 門 推 薦用Python分析NBA球員技術抖音同款!用Python小套路來撩女神故宮下雪!我用Python畫了一組手繪圖Python技術知識清單(數據科學)Python技術知識清單(網絡爬蟲)

社區注冊會員

總結

以上是生活随笔為你收集整理的python怎么避免浅拷贝_深度解读Python深拷贝与浅拷贝问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲图区欧美 | 国产第三区 | 午夜视频在线看 | 日韩欧美在线视频观看 | 欧美日本在线观看 | 国产精品人八做人人女人a级刘 | 91在线免费网站 | 无码人妻精品一区二区三区9厂 | 日韩一二三四区 | 国产精品日韩一区二区三区 | 99在线小视频 | 麻豆一区二区 | 久久综合欧美 | 精品国产亚洲一区二区麻豆 | 1区2区视频 | 国产做爰全过程免费视频 | 国产妇女馒头高清泬20p多 | 中文字幕亚洲第一 | 日韩视频一区二区三区在线播放免费观看 | 成年网站免费观看 | 99久久久无码国产精品性 | 免费观看理伦片在线播放视频软件 | 91精品国产成人观看 | 亚洲黄色在线播放 | 成人3d动漫一区二区三区 | 四虎色 | 韩日精品在线 | 成人av电影在线观看 | 日日干夜夜骑 | 精品久久毛片 | 99成人在线观看 | aaaaaaa毛片 | 成人动漫av在线 | 好吊一区| 免费观看视频一区 | 久久国产精品亚洲 | 欧美zozo | 国产精品视频观看 | 久久y| 亚洲乱码日产精品bd在线观看 | 欧美成人女星 | aaaa一级片| 欧美日韩在线观看视频 | 国产精品第3页 | 国产91av在线播放 | 蜜臀av一区 | 欧美电影一区 | 毛片.com | 丁香婷婷网 | 国产中文字幕网 | 中文字幕免费在线看线人动作大片 | 国产又黄又爽又色 | 97狠狠操 | 天天射夜夜撸 | 免费中文视频 | 尹人av| 国模小黎自慰gogo人体 | 精品人妻少妇嫩草av无码专区 | 波多野结衣在线播放视频 | 美女黄视频在线观看 | 久久久久中文字幕亚洲精品 | 午夜精品国产精品大乳美女 | 久久久资源网 | 日韩在线观看视频一区二区 | 人妖videosex高潮另类 | 国产毛片毛片毛片 | 污视频免费在线观看网站 | 都市激情校园春色亚洲 | 国产在视频线精品视频 | 精品久久久无码中文字幕 | 日韩最新| 久久看看| 日韩裸体视频 | 呦女精品| 成人精品视频在线播放 | 欧美在线一区二区 | 精品视频一二三区 | 成人激情开心 | 日日爱夜夜爱 | 亚洲美女自拍偷拍 | 亲子乱aⅴ一区二区三区 | 国产免费成人在线视频 | 国产精品久久久久久久久久久不卡 | 制服丝袜先锋影音 | 精品一区二区三区入口 | 偷拍网亚洲 | 色婷婷综合成人av | 啊v视频在线观看 | 日韩伊人网 | 老司机黄色片 | 亚洲经典久久 | 久久aaa | 超碰视屏 | 日本一级大片 | 一区二区三区四区免费观看 | 精品国产不卡 | 一本色道久久88加勒比—综合 | 欧美性生交大片免费看app麻豆 | av片在线观看网站 |