python中的賦值與深淺拷貝

2022-09-01 22:09:16 字數 3176 閱讀 9380

python當中對於拷貝,分為兩種型別。一種是數字和字串,另一種就是列表、元組、字典等其他型別了。

舉個栗子:

a1 = 123123

a2 = 123123

# a2 = a1 # 賦值

print(id(a1)) # 通過id()函式來列印變數在記憶體當中的位址

print(id(a2))

輸出結果是:

1959780298352

1959780298352

在以上**塊當中,a2與a1所賦的值是一樣的,都是數字123123。因為python有乙個重用機制,對於同乙個數字,python並不會開闢一塊新的記憶體空間,而是維護同一塊記憶體位址,只是將該數字對應的記憶體位址的引用賦值給變數a1和a2。所以根據輸出結果,a1和a2其實對應的是同一塊記憶體位址,只是兩個不同的引用罷了。同樣的,對於a2 = a1,其實效果等同於「a1 = 123123; a2 = 123123」,它也就是將a1指向123123的引用賦值給a2。字串跟數字的原理雷同,如果把123123改成「abcabc」也是一樣的。

import copy  # 使用淺拷貝需要匯入copy模組

a1 = 123123

a3 = copy.copy(a1) # 使用copy模組裡的copy()函式就是淺拷貝了

print(id(a1))

print(id(a3))

輸出結果是:

35233168

35233168

通過使用copy模組裡的copy()函式來進行淺拷貝,把a1拷貝乙份賦值給a3,檢視輸出結果發現,a1和a3的記憶體位址還是一樣。

舉個栗子:

import copy

a1 = 123123

a4 = copy.deepcopy(a1) # 深拷貝是用copy模組裡的deepcopy()函式

print(id(a1))

print(id(a4))

輸出結果為:

31432080

31432080

檢視結果發現,對於深拷貝,數字和字串在記憶體當中用的也是同一塊位址。

二、字典、列表、元組等其他型別的拷貝

舉個栗子:

n1 = 

n2 = n1 # 賦值

print(id(n1))

print(id(n2))

輸出結果:

2235551677536

2235551677536

我們的栗子當中用了乙個字典n1,字典裡面巢狀了乙個列表,當我們把n1賦值給n2時,記憶體位址並沒有發生變化,因為其實它也是只是把n1的引用拿過來賦值給n2而已。(我們用了乙個字典來舉例,其他型別也是一樣的)

原理如下圖:

舉個栗子:

import copy

n1 =

n3 = copy.copy(n1) # 淺拷貝

print(id(n1))

print(id(n3))

print(id(n1["k3"]))

print(id(n3["k3"]))

輸出結果:

舉個栗子:

import copy

n1 =

n4 = copy.deepcopy(n1) # 深拷貝

print(id(n1))

print(id(n4))

print(id(n1["k3"]))

print(id(n4["k3"]))

輸出結果:

31157560

35463600

35947144

35947336

通過以上結果發現,進行深拷貝時,字典裡面的第一層和裡面巢狀的位址都已經變了。對於深拷貝,它會拷貝多層,將第二層的列表也拷貝乙份,如果還有第三層巢狀,那麼第三層的也會拷貝,但是對於裡面的最小元素,比如數字和字串,這裡就是「wu」,123,「alex」,678之類的,按照python的機制,它們會共同指向同乙個位置,它的記憶體位址是不會變的。原理如下圖:

舉個實際應用場景的栗子。

我們在維護伺服器資訊的時候,經常會要更新伺服器資訊,這時我們重新乙個乙個新增是比較麻煩的,我們可以把原資料型別拷貝乙份,在它的基礎上做修改。

栗子一、使用淺拷貝

import copy

dic =

# 定義了乙個字典,儲存伺服器資訊。

print('before', dic)

new_dic = copy.copy(dic)

new_dic['cpu'][0] = 50 # 更新cpu為50

print(dic)

print(new_dic)

輸出結果為:

before 

這時我們會發現,使用淺拷貝時,我們修改新的字典的值之後,原來的字典裡面的cpu值也被修改了,這並不是我們希望看到的。

栗子二、使用深拷貝

import copy

dic =

print('before', dic)

new_dic = copy.deepcopy(dic)

new_dic['cpu'][0] = 50

print(dic)

print(new_dic)

輸出結果:

before 

使用深拷貝的時候,發現只有新的字典的cpu值被修改了,原來的字典裡面的cpu值沒有變。大功告成!

python中的深淺拷貝與賦值。

賦值 賦值就是乙個變數引用乙個變數的值。這兩個變數共用乙個記憶體位址。當使用可變資料結構時 如 list,dict,set 其中乙個變數的值改變,會使另乙個變數的值也發生改變,但記憶體位址不改變。a 1 2,3 b ab 1 4print id a a,id b b 1992269718152 1,...

python中的賦值與深淺拷貝

在python中,只有在int和字串,元組等不可變型別中,與深淺拷貝的結果一樣 因為其是不可變型別,都是連記憶體位址一起 複製 了。而在list,dict,set中,深淺拷貝並沒有複製 位址 複製 記憶體位址的結果就是,之後的操作會影響原來的物件。以下所有的內容都是基於記憶體位址來說的。1.int型...

Python中的賦值與深淺拷貝

鑑於對很多初學程式設計的小夥伴來說,對於賦值和深淺拷貝的用法有些疑問,所以我就結合python變數儲存的特性從記憶體的角度來談一談賦值和深淺拷貝 一些基本的定義 幾個術語的解釋 深淺拷貝的作用 對於不可變物件的深淺拷貝 不可變物件型別 這個不可變物件型別裡面不能包含可變物件型別,如元祖裡面包含列表就...