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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

Python——赋值、浅拷贝、深拷贝

發(fā)布時(shí)間:2024/4/14 python 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python——赋值、浅拷贝、深拷贝 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

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

  在學(xué)習(xí)過(guò)程中,一開(kāi)始對(duì)淺拷貝理解很模糊。不過(guò)經(jīng)過(guò)一系列的實(shí)驗(yàn)后,我發(fā)現(xiàn)對(duì)這三者的概念有了進(jìn)一步的了解。

?

  一、賦值

  賦值算是這三種操作中最常見(jiàn)的了,我們通過(guò)一些例子來(lái)分析下賦值操作:

  str例

?

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

?

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

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

?

  list例

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

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

  因?yàn)閟tr是不可變的,所以同樣是'hello'只有一個(gè)地址,但是list是可變的,所以必須分配兩個(gè)地址。

?

  這時(shí),我們希望探究以上兩種情況如果修改值會(huì)如何?

  str例

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

  這時(shí)a的地址和值變了,但是b, c地址和值都未變。因?yàn)閟tr的不可變性,a要重新賦值則需重新開(kāi)辟內(nèi)存空間,所以a的值改變,a指向的地址改變。b, c由于'hello'的不變性,不會(huì)發(fā)生改變。

?

  list例

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

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


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

  我們均用list作為例子。

  二、淺拷貝

1 >>> a = ['hello', [123, 234]] 2 >>> b = a[:] 3 >>> [id(x) for x in a,b] 4 [4496003656, 4496066752] 5 >>> [id(x) for x in a] 6 [4496091584, 4495947536] 7 >>> [id(x) for x in b] 8 [4496091584, 4495947536]

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

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

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

  a中第一個(gè)元素str改變,但是b中未改變;a中第二個(gè)元素改變,b中也改變。這就符合不可變的對(duì)象修改會(huì)開(kāi)辟新的空間,可變的對(duì)象修改不會(huì)開(kāi)辟新空間。也進(jìn)一步證明了淺拷貝僅僅是復(fù)制了容器中元素的地址


?

  二、深拷貝

1 >>> from copy import deepcopy 2 >>> a = ['hello', [123, 234]] 3 >>> b = deepcopy(a) 4 >>> [id(x) for x in a, b] 5 [4496066824, 4496066680] 6 >>> [id(x) for x in a] 7 [4496091584, 4496067040] 8 >>> [id(x) for x in b] 9 [4496091584, 4496371792]

  深拷貝后,可以發(fā)現(xiàn)a, b地址以及a, b中元素地址均不同。這才是完全拷貝了一個(gè)副本

  修改a的值后:

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

  從Line4,5中可以發(fā)現(xiàn)僅僅a修改了,b沒(méi)有任何修改。因?yàn)閎是一個(gè)完全的副本,元素地址均與a不同,a修改,b不受影響


  總結(jié):

?

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

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

  3. 深拷貝是在另一塊地址中創(chuàng)建一個(gè)新的變量或容器,同時(shí)容器內(nèi)的元素的地址也是新開(kāi)辟的,僅僅是值相同而已,是完全的副本。也就是說(shuō)(新瓶裝新酒)。

?

轉(zhuǎn)載于:https://www.cnblogs.com/PythonMrChu/p/10673507.html

總結(jié)

以上是生活随笔為你收集整理的Python——赋值、浅拷贝、深拷贝的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。