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

歡迎訪問 生活随笔!

生活随笔

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

python

python默认深拷贝_Python 深拷贝与浅拷贝

發(fā)布時(shí)間:2025/3/8 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python默认深拷贝_Python 深拷贝与浅拷贝 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

首先分享Python里面的數(shù)據(jù)類型

1、不可變類型:Number(數(shù)字)、String(字符串)、Tuple(元組)。

不可變數(shù)據(jù)類型在第一次聲明賦值的時(shí)候, 會(huì)在內(nèi)存中開辟一塊空間, 用來(lái)存放這個(gè)變量被賦的值,? 而這個(gè)變量實(shí)際上存儲(chǔ)的, 并不是被賦予的這個(gè)值, 而是存放這個(gè)值所在空間的內(nèi)存地址, 通過這個(gè)地址, 變量就可以在內(nèi)存中取出數(shù)據(jù)了. 所謂不可變就是說(shuō), 我們不能改變這個(gè)數(shù)據(jù)在內(nèi)存中的值, 所以當(dāng)我們改變這個(gè)變量的賦值時(shí), 只是在內(nèi)存中重新開辟了一塊空間, 將這一條新的數(shù)據(jù)存放在這一個(gè)新的內(nèi)存地址里, 而原來(lái)的那個(gè)變量就不在引用原數(shù)據(jù)的內(nèi)存地址而轉(zhuǎn)為引用新數(shù)據(jù)的內(nèi)存地址了.

如圖:

In [11]: a = 1 #int為不可變類型,賦值

?

In [12]: id(a) #查看a地址

Out[12]: 4541615920In [13]: id(1) #查看數(shù)字1的地址

Out[13]: 4541615920?

In [14]: a = 2 #為a重新賦值

?

In [15]: id(a) #查看a地址,指向新的內(nèi)存地址

Out[15]: 4541615952?

In [16]: id(2)

Out[16]: 4541615952?

In [17]: id(1)

Out[17]: 4541615920

In [28]: a = "hello" #為a賦值 hello

?

In [29]: b = a #將a賦值給a

?

In [30]: id(a)

Out[30]: 4572905712?

In [31]: id(b) #通過查看a和b的地址,說(shuō)明a和b指向同一個(gè)地址

Out[31]: 4572905712?

In [32]: b = "hi" #為b賦值 hi

?

In [33]: a #查看a未被修改

Out[33]: 'hello'?

In [34]: id(a) #查看a地址未發(fā)生修改

Out[34]: 4572905712?

In [35]: id(b) #查看b指向新的地址,說(shuō)明b=a時(shí),是將a的引用指向b

Out[35]: 4544178736

b=a直接賦值時(shí),默認(rèn)是淺拷貝傳遞對(duì)象的引用而已,原始數(shù)據(jù)若為不可變類型時(shí),被賦值的b改變時(shí),相當(dāng)于在內(nèi)存中重新開辟了一塊空間, 將這一條新的數(shù)據(jù)存放在這一個(gè)新的內(nèi)存地址里, 而原來(lái)的那個(gè)變量就不在引用原數(shù)據(jù)的內(nèi)存地址而轉(zhuǎn)為引用新數(shù)據(jù)的內(nèi)存地址了.

2、可變類型:Set(集合)、List(列表)、Dictionary(字典)。

當(dāng)數(shù)據(jù)類型對(duì)應(yīng)的變量的值發(fā)生改變時(shí),它對(duì)應(yīng)的內(nèi)存地址也會(huì)發(fā)生改變,即當(dāng)?e?=?[1,2]?時(shí),是e指向列表[1,2]對(duì)象,而不是將e指向列表[1,2]的地址

如圖:

In [10]: e = [1,2]

?

In [11]: id(e)

Out[11]: 4408548080?

In [12]: id([1,2]) #e指向[1,2]對(duì)象,而不是[1,2]的地址

Out[12]: 4408714656

In [10]: e = [1,2] #給變量e賦值可變類型列表[1,2]

?

In [11]: id(e) #查看e地址

Out[11]: 4408548080?

In [12]: id([1,2]) #查看列表[1,2]地址

Out[12]: 4408714656?

In [13]: f = e #將e賦值給f,兩者共享同一個(gè)列表[1,2]對(duì)象

?

In [14]: id(f) #查看f地址,其實(shí)是將c指向于e的引用地址,而非列表[1,2]的實(shí)際地址

Out[14]: 4408548080?

In [15]: e[0] = 11 #通過e修改列表內(nèi)元素

?

In [16]: e

Out[16]: [11, 2]

?

In [17]: f #查看f中對(duì)應(yīng)元素同樣被修改,驗(yàn)證e和f指向一個(gè)引用對(duì)象,說(shuō)明f=e時(shí),是將e的對(duì)象的地址指向f

Out[17]: [11, 2]

f?=?e直接賦值時(shí),默認(rèn)是淺拷貝傳遞對(duì)象的引用而已,原始數(shù)據(jù)e若為可變類型發(fā)生變化,被賦值的f也會(huì)做相同的改變。

3. 淺拷貝

淺拷貝是對(duì)于一個(gè)對(duì)象的頂層拷貝

通俗的理解是:拷貝了引用,并沒有拷貝內(nèi)容

In [36]: a = [1,2]

?

In [37]: b =a

?

In [38]: id(a)

Out[38]: 4573291056?

In [39]: id(b) #淺拷貝,a和b地址相同,說(shuō)明b=a是對(duì)a引用的拷貝

Out[39]: 4573291056

通過上面的結(jié)果,說(shuō)明當(dāng)給一個(gè)變量賦值時(shí)。其實(shí)就是講數(shù)據(jù)的引用復(fù)制了一份給另外一個(gè)變量 ,就是屬于簡(jiǎn)單的淺拷貝

In [36]: a = [1,2]

?

In [37]: b =a

?

In [38]: id(a)

Out[38]: 4573291056?

In [39]: id(b)

Out[39]: 4573291056?

In [40]: a[0] = 11?

In [41]: a #a中元素被修改

Out[41]: [11, 2]

?

In [42]: b #b中元素被修改

Out[42]: [11, 2]

通過上面的結(jié)果,說(shuō)明通過任何一個(gè)引用修改可變變量之后,另外一個(gè)變量的值也發(fā)生了變化。

In [24]: g = [2,3]

?

In [25]: h = copy.copy(g) #淺拷貝

?

In [26]: id(g)

Out[26]: 4409269536?

In [27]: id(h)

Out[27]: 4408716176?

In [28]: id([2,3])

Out[28]: 4408685824?

In [30]: id(2) #獲取2的地址

Out[30]: 4378861392?

In [31]: id(g[0]) #獲取g[0]位置的地址

Out[31]: 4378861392?

In [32]: id(h[0]) #獲取h[0]位置的地址

Out[32]: 4378861392

通過上面的結(jié)果,說(shuō)明淺拷貝只是對(duì)外層引用的拷貝,內(nèi)層地址一樣。

In [33]: a = [11,22]

?

In [34]: b = [33,44]

?

In [35]: c =[a,b]

?

In [36]: id(a)

Out[36]: 4408713536?

In [37]: id(b)

Out[37]: 4408547680?

In [38]: id(c)

Out[38]: 4408615712?

In [39]: d = copy.copy(c) #對(duì)c進(jìn)行淺拷貝,得到d

?

In [40]: id(d) #查看d地址

Out[40]: 4409421248?

In [41]: id(d[0]) #查看d[0]位置元素地址,與a地址相同,說(shuō)明只進(jìn)行外層拷貝

Out[41]: 4408713536?

In [42]: id(d[1]) #查看d[1]位置元素地址,與b地址相同,說(shuō)明只進(jìn)行外層拷貝

Out[42]: 4408547680?

In [43]: a.append(55) #給a列表添加元素

?

In [44]: c #查看c中元素也發(fā)生變化

Out[44]: [[11, 22, 55], [33, 44]]

?

In [45]: d #查看d中元素也發(fā)生變化,說(shuō)明是對(duì)外層的拷貝

Out[45]: [[11, 22, 55], [33, 44]]

?

In [46]: d.append(66) #給d中添加元素

?

In [47]: d #查看d中元素發(fā)生變化

Out[47]: [[11, 22, 55], [33, 44], 66]

?

In [48]: c #查看c中元素未發(fā)生變化,說(shuō)明d未外層拷貝

Out[48]: [[11, 22, 55], [33, 44]]

通過上面的結(jié)果,說(shuō)明淺拷貝只是對(duì)外層引用的拷貝,內(nèi)層地址一樣,修改外層,拷貝的新對(duì)象不會(huì)發(fā)生變化,修改內(nèi)層元素,拷貝的新對(duì)象會(huì)發(fā)生變化。

4. 深拷貝

深拷貝是對(duì)于一個(gè)對(duì)象所有層次的拷貝(遞歸), 所以原始對(duì)象的改變不會(huì)造成深拷貝里任何子元素的改變

In [61]: a = [11,22]

?

In [62]: b = [33,44]

?

In [63]: c =[a,b]

?

In [64]: c

Out[64]: [[11, 22], [33, 44]]

?

In [65]: d = copy.deepcopy(c) #深拷貝得到d

?

In [66]: d

Out[66]: [[11, 22], [33, 44]]

?

In [67]: f = copy.copy(c) #淺拷貝得到f

?

In [68]: f

Out[68]: [[11, 22], [33, 44]]

?

In [69]: a.append(55) #a中添加元素55

?

In [70]: d #深拷貝的d中沒有修改,說(shuō)明是對(duì)內(nèi)層也進(jìn)行copy

Out[70]: [[11, 22], [33, 44]]

?

In [71]: f #淺拷貝的f中發(fā)生變化,說(shuō)明是只對(duì)外層進(jìn)行了copy

Out[71]: [[11, 22, 55], [33, 44]]

總結(jié)

以上是生活随笔為你收集整理的python默认深拷贝_Python 深拷贝与浅拷贝的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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