亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【python】 一文弄懂淺拷貝與深拷貝

系統 1520 0

一、可變對象與非可變對象

  想要理解淺拷貝與深拷貝就必須得先明白可變對象與非可變對象。

  可變對象有: list ,dict ,set

??????? 不可變對象有:int ,float ,bool ,str ,tuple 。

  兩者區別:對于可變對象,其值改變是在原地址上操作,不會創建新的內存地址。對于不可變對象其值改變是直接創建新的內存地址。

二、賦值操作符‘=’表示對象的引用。

python里面的?賦值操作符‘=’實際上是對象的引用,其并沒有進行復制操作。如果如果賦值操作符右邊的操作數是字面值,比如字符串或者數字,那么左邊的操作數被設為一個對象的引用,該對象將指向存放字面值得內存對象。(a=1,a指向1的內存對象)。如果右邊的操作數是一個對象引用,那么左邊的操作數將設置為一個對象引用,并與右邊的操作數是一個對象引用,并與右邊的操作數指向相同的對象。(b=a,則a,b均指向1的內存對象)

            
              >>> a=1       #a引用對象1(指向1的地址)
>>> b=a       # b引用對象a實際上也是引用對象1 ?。ǎ庵赶颍钡牡刂罚?>>> id(a)     
94474006287136
>>> id(b)
94474006287136
>>> a=2           #a引用對象2,由于對象2相對對象1發生了改變,則重新創建新的內存里面                    存的是對象2?。ǎ嶂赶颍蔡幍牡刂罚?>>> id(a)
94474006287168
>>> id(b)       # b繼續引用之前的對象1 (b還是指向之前1的地址不變)
94474006287136
>>> 
>>> a=[1,2,3,4]
>>> b=a
>>> b
[1, 2, 3, 4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4, 5]

            
          

由上可以發現列表a賦值給b時,實際上a和b都指向同一內存地址。由于列表a是可變對象,對a進行append操作后是在原地址上操作,所以b也跟著改變了。

二、 淺拷貝 copy.copy()

  1.對于不可變類型 Number String Tuple,淺復制僅僅是地址指向,不會開辟新空間。

            
              >>> a='hello world'
>>> b=a
>>> id(a)
140620341876400
>>> id(b)
140620341876400
>>> c=copy.copy(a)
>>> c
'hello world'
>>> id(c)
140620341876400
>>> 

            
          

對于下面的情況:將a的地址指向改變下,但是b和c的地址仍然不變,指向原來的地址。

            
              >>> a=5   # 將a的地址指向由‘hello world'改為指向5
>>> id(a)
94474006287264
>>> id(b)
140620341876400
>>> id(c)
140620341876400
>>> 

            
          

 ?。玻畬τ诳勺冾愋?List、Dictionary、Set,淺復制會開辟新的內存存放其指向的地址(僅僅是最頂層開辟了新的內存,里層的元素地址還是一樣的)

            
              >>> a=[1,2,3,[4,5,6],7,8]   #列表中子對象(子列表[4,5,6])
>>> b=a
>>> c=copy.copy(a)
>>> id(a)        
140620341875976
>>> id(b)
140620341875976
>>> id(c)           # 淺copy 外層開辟新的內存,c的內存地址與a不一樣
140620341876104
>>> id(a[3])         # 里層的內存地址
140620341814920
>>> id(d[3])
140620341875720
>>> id(c[3])         # 淺拷貝后的里層的內存地址與原對象的里層內存地址一樣。里層在淺copy時                 作為公共部分使用,淺拷貝時這部分不會重新創建新的內存
140620341814920

            
          

 ?。? 可變類型 (只有可變類型才能對應后面的改變)淺拷貝后, 改變 原始對象中為可變類型的元素的值,會同時影響拷貝對象的;改變原始對象中為不可變類型的元素的值,只有原始類型受影響。

            
              >>> a=[1,2,3,{'a':'A'}]
>>> c=copy.copy(a)
>>> id(a)
140620341875976
>>> id(c)
140620341680264
>>> a[0]=0
>>> a
[0, 2, 3, {'a': 'A'}]
>>> c
[1, 2, 3, {'a': 'A'}]
>>> id(a[0])
94474006287104
>>> id(c[0])
94474006287136
>>> a[3]['a']='AAA'
>>> a
[0, 2, 3, {'a': 'AAA'}]
>>> c
[1, 2, 3, {'a': 'AAA'}]
>>> id(a[3])
140620366602104
>>> id(c[3])
140620366602104
>>> 

            
          

  總結:淺拷貝(復制) 只是拷貝了對象引用,而非對象本身。 對于不可變數據,淺拷貝就當于我們所理解的復制,此時也等價于深拷貝。對于可變數據類型,其元素是不可變時與上述一樣,如果是可變元素時, 比如列表中有嵌套列表,嵌套列表的引用也被復制,當嵌套列表改變時,其內存地址不變即淺拷貝后其嵌套列表也是跟著變得。

三、深拷貝copy.deepcopy()

??????? 深拷貝就是通常我們所理解的,完全的拷貝并重新創建新的內存空間(包括外層和里層)。

            
              >>> a=[1,2,3,[4,5,6]]
>>> b=copy.deepcopy(a)
>>> id(a)
140620341875976
>>> id(b)
140620341876104
>>> a[3][0]=0
>>> a
[1, 2, 3, [0, 5, 6]]
>>> b
[1, 2, 3, [4, 5, 6]]

            
          

四、其他等價的淺拷貝。

? ? ? ?除了淺拷貝copy.copy外,對于列表還是其他的操作等價于淺拷貝。比如切片和類型名作為函數。

【python】 一文弄懂淺拷貝與深拷貝_第1張圖片

使用類型名作為函數的還有如下

copy_of_dict=dict(d)

copt_of_set=set(s)

?


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!?。?/p>

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品人人| 中文字幕视频二区 | 99在线观看视频免费 | 97av在线视频 | 亚洲欧美中文字幕高清在线一 | 香蕉久久综合 | 欧美美女被爆操 | 99国产精品欧美久久久久久影院 | 欧美日韩中文字幕在线视频 | 色酷综合 | 手机看片久久 | 女性一级全黄生活片免费看 | 亚洲成人高清在线 | 久久精品国产亚洲麻豆小说 | 亚洲精品在线不卡 | 色噜噜狠狠狠狠色综合久一 | 五月花激情网 | 国产黄mmd在线观看免费 | 香蕉视频在线观看网站 | 色香欲综合成人免费视频 | 天天爽夜夜爽视频 | 国产精品99一区二区三区 | 亚洲天天更新 | 亚洲欧美精品日韩欧美 | 狠狠夜夜| 色网站在线看 | 久久99久久99小草精品免视看 | 亚洲系列中文字幕一区二区 | 国产高清一级毛片在线不卡 | 国产一区二区三区乱码网站 | 奇米影视在线视频 | 国内外成人免费视频 | 久久婷婷午色综合夜啪 | 亚洲高清免费视频 | 国产精品爱久久久久久久三级 | 久久精品国产四虎 | 老子影院午夜 | 国产成人亚洲综合a∨婷婷 国产成人亚洲综合欧美一部 | 天天操综合网 | 波多野结衣一区二区三区在线观看 | 欧美成人亚洲欧美成人 |