>>a='hello'>>>b='hello'>>>c=a>>>[id(x)forxina,b,c][4404120000,4404120000,4404120000]由以上指" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python中的賦值、淺拷貝、深拷貝介紹

系統 1607 0

和很多語言一樣,Python中也分為簡單賦值、淺拷貝、深拷貝這幾種“拷貝”方式。

在學習過程中,一開始對淺拷貝理解很模糊。不過經過一系列的實驗后,我發現對這三者的概念有了進一步的了解。

一、賦值

賦值算是這三種操作中最常見的了,我們通過一些例子來分析下賦值操作:

str例

復制代碼 代碼如下:

>>> a = 'hello'
>>> b = 'hello'
>>> c = a
>>> [id(x) for x in a,b,c]
[4404120000, 4404120000, 4404120000]

由以上指令中,我們可以發現a, b, c三者的地址是一樣的。所以以上賦值的操作就相當于c = a = b = 'hello'。

賦值是系統先給一個變量或者對象(這里是'hello')分配了內存,然后再將地址賦給a, b, c。所以它們的地址是相同的。

list例

復制代碼 代碼如下:

>>> a = ['hello']
>>> b = ['hello']
>>> c = a
>>> [id(x) for x in a,b,c]
[4403975952, 4404095096, 4403975952]

但是這種情況卻不一樣了,a和b的地址不同。為何?

因為str是不可變的,所以同樣是'hello'只有一個地址,但是list是可變的,所以必須分配兩個地址。

這時,我們希望探究以上兩種情況如果 修改值 會如何?

str例

復制代碼 代碼如下:

>>> a = 'world'
>>> [id(x) for x in a,b,c]
[4404120432, 4404120000, 4404120000]
>>> print a, b, c
world hello hello

這時a的地址和值變了,但是b, c地址和值都未變。因為str的不可變性,a要重新賦值則需重新開辟內存空間,所以a的值改變,a指向的地址改變。b, c由于'hello'的不變性,不會發生改變。

list例

復制代碼 代碼如下:

>>> a[0] = 'world'
>>> [id(x) for x in a,b,c]
[4403975952, 4404095096, 4403975952]
>>> print a, b, c
['world'] ['hello'] ['world']

這時a, c的值和地址均改變,但二者仍相同,b不改變。由于list的可變性,所以修改list的值不需要另外開辟空間,只需修改原地址的值。所以a, c均改變。

在了解了以上的不同點之后,我們就能很好地分析淺拷貝和深拷貝了。

我們均用list作為例子。

二、淺拷貝

復制代碼 代碼如下:

>>> a = ['hello', [123, 234]]
>>> b = a[:]
>>> [id(x) for x in a,b]
[4496003656, 4496066752]
>>> [id(x) for x in a]
[4496091584, 4495947536]
>>> [id(x) for x in b]
[4496091584, 4495947536]

Line3,4可以看出a, b地址不同,這符合list是可變的,應開辟不同空間。那淺拷貝就是拷貝了一個副本嗎?再看Line5 - 8,我們發現a, b中元素的地址是相同的。如果說字符串'hello'地址一致還能理解,但是第二個元素是list地址仍一致。 這就說明了淺拷貝的特點,只是將容器內的元素的地址復制了一份 。

接著我們嘗試修改a, b中的值:

復制代碼 代碼如下:

>>> a[0] = 'world'
>>> a[1].append(345)
>>> print 'a = ', a, '\n\r', 'b = ', b
a =? ['world', [123, 234, 345]]
b =? ['hello', [123, 234, 345]]

a中第一個元素str改變,但是b中未改變;a中第二個元素改變,b中也改變。這就符合不可變的對象修改會開辟新的空間,可變的對象修改不會開辟新空間。也進一步證明了 淺拷貝僅僅是復制了容器中元素的地址 。

三、深拷貝

復制代碼 代碼如下:

>>> from copy import deepcopy
>>> a = ['hello', [123, 234]]
>>> b = deepcopy(a)
>>> [id(x) for x in a, b]
[4496066824, 4496066680]
>>> [id(x) for x in a]
[4496091584, 4496067040]
>>> [id(x) for x in b]
[4496091584, 4496371792]

深拷貝后,可以發現a, b地址以及a, b中元素地址均不同。這才是完全 拷貝了一個副本 。

修改a的值后:

復制代碼 代碼如下:

>>> a[0] = 'world'
>>> a[1].append(345)
>>> print 'a = ', a, '\n\r', 'b = ', b
a =? ['world', [123, 234, 345]]
b =? ['hello', [123, 234]]

從Line4,5中可以發現僅僅a修改了,b沒有任何修改。 因為b是一個完全的副本,元素地址均與a不同,a修改,b不受影響 。

總結:

1. 賦值是將一個對象的地址賦值給一個變量,讓變量指向該地址( 舊瓶裝舊酒 )。

2. 淺拷貝是在另一塊地址中創建一個新的變量或容器,但是容器內的元素的地址均是源對象的元素的地址的拷貝。也就是說新的容器中指向了舊的元素( 新瓶裝舊酒 )。

3. 深拷貝是在另一塊地址中創建一個新的變量或容器,同時容器內的元素的地址也是新開辟的,僅僅是值相同而已,是完全的副本。也就是說( 新瓶裝新酒 )。


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久久国产一区 | 国产精品国产精品国产专区不卡 | 亚洲欧美激情精品一区二区 | 91免费片 | 久久夏同学国产免费观看 | 欧美成年视频 | 久久综合九九 | 免费久久99精品国产婷婷六月 | 在线观看www| 国产高清免费视频 | 日本不卡一区 | 国产成人精品一区二区三区电影 | 欧美视频亚洲视频 | 日本黄色小视频 | 手机在线看片国产日韩生活片 | 一级午夜a毛片免费视频 | 欧美精品 在线观看 | 色综合天天综合网国产成人网 | 欧美成在线播放 | 午夜国产精品视频在线 | 草草影院网站 | 久久中文字幕久久久久91 | 中文字幕一区在线观看视频 | 亚洲欧洲精品成人久久曰影片 | 日本高清免费h色视频在线观看 | 性69式视频在线观看免费 | 另类婷婷 | 香港三级日本三级韩国a | 精品国产九九 | 免费欧美黄色网址 | 免费大片黄在线观看 | 日本黄色录像 | 奇米影视888狠狠狠777九色 | 日韩中文一区二区三区 | 老司机午夜性大片 | 欧美性一区二区三区 | 激情五月激情综合网 | 国产成人精品福利网站在线观看 | 久草精彩视频 | 色站网 | 久久黄视频|