賦值 淺拷貝 深拷貝之我理解

2022-05-07 16:54:17 字數 3031 閱讀 4381

(一)2個為什麼

先通過2個為什麼來了解一下python記憶體中變數的儲存情況。

>>> name = [1,2,3,["

alex

","rain"]]

>>> name2 =name.copy() # 將原列表copy乙份賦值給name2

>>> print

(name)

[1, 2, 3, ['

alex

', '

rain']]

>>> print

(name2)

[1, 2, 3, ['

alex

', '

rain']]

>>>

name與name2相同

第乙個為什麼:

>>> name[1] = -2

>>> print

(name)

[1, -2, 3, ['

alex

', '

rain']]

>>> print

(name2)

[1, 2, 3, ['

alex

', '

rain']]

>>>

name[1]改變後,name改變了而name2沒有改變,為什麼?

第二個為什麼:

>>> name[3][0] = "

alex

">>> print

(name)

[1, -2, 3, ['

alex

', '

rain']]

>>> print

(name2)

[1, 2, 3, ['

alex

', '

rain']]

>>>

將name[3][0]的值改後,name改變了,name2也改變了,為什麼?

第乙個為什麼和第二個為什麼都對列表進行了更改,而結果為什麼不一樣尼?

首先我們要清楚,列表name的元素是存在於多塊記憶體空間中的,不是在同一塊;每個元素的記憶體位址都是獨立的。

變數name等於[1,2,3,["alex","rain"]]這個含有這些元素的列表的時候,記憶體中發生了2件事:一是變數name是個列表,開闢了一塊記憶體空間;二是列表裡的每乙個元素各自開闢了屬於自己的記憶體空間。name列表開闢的記憶體空間裡存的不是元素,而是每個元素的記憶體位址。每乙個元素比作是家的話,name列表的記憶體空間裡存的就是郵寄到你家的包裹上的位址,是乙個指向。

name2 copy name,只是copy了name中的元素(一級元素)的記憶體位址,即將id(1),id(2),id(3)等這些元素的記憶體位址複製到了name2的記憶體空間裡了。

解答第乙個為什麼:

將name中的2改為-2,name內的2的記憶體位址會被擦除,然後將新開闢的-2的記憶體位址佔位到此處。由於2的記憶體位址還被name2引用,所以2的記憶體不會被釋放,依然存在。

對於第乙個為什麼,name的第乙個元素為-2,name2的第乙個元素為2,因為這2個的記憶體位址不同,所以位址所指向的資料(在記憶體裡以十六進製制數表示)就不同。記憶體位址不同,資料不同。

解答第二個為什麼:

要區分清楚列表的記憶體位址和列表中元素的記憶體位址是不一樣的,不要混淆

name2 copy name的時候,copy了每個元素(一級元素)的記憶體位址。name中元素['alex', 'rain']這個小列表的記憶體位址也被複製,即name中的小列表的記憶體位址與name2中的小列表的記憶體位址是一樣的,也就是說name2中的小列表沒有開闢新的空間,而是引用了name中小列表的空間。id(name[3]) = id(name2[3]).

第二個為什麼中,對name內的小列表中的元素"alex"進行了全大寫更改(過程:"alex"開闢了一塊新的空間,將這塊新空間的位址放到小列表中的索引為0的位置),即小列表(巢狀列表)內的元素的發生改變,而小列表的記憶體位址沒有發生變化,name2中的小列表的記憶體位址與name中的小列表的記憶體位址一樣,所以name中小列表的值發生變化,name2中的小列表的值也會變化。記憶體位址相同,指向的資料也相同

(二)賦值、淺拷貝、深拷貝

1、賦值:傳遞物件的引用而已,原始列表name改變,被賦值的n也會做相同的改變。(見下圖,圖畫的不好)

2.淺拷貝:拷貝父物件,不會拷貝物件的內部的子物件。即拷貝列表name裡面的一級元素的記憶體位址,不拷貝name裡的小列表裡的元素的記憶體位址。

3.深拷貝:copy 模組的 deepcopy 方法,完全拷貝了父物件及其子物件。即name2不僅拷貝了name中一級元素(1,2,3,["alex","rain"])的的記憶體位址,也拷貝了巢狀列表,["alex","rain"]裡面的"alex"和"rain"的記憶體位址。

name比作是乙個容器的話,我們把name裡的每樣東西複製了乙份放到另乙個容器name2裡。name裡有東西丟失的話,name2裡的還在,而name2這個容器是新開闢的空間。在第乙個容器裡的東西還未變化之前,2個不同容器裝了同樣的東西。

非容器型別的沒有拷貝這一說。

淺拷貝 深拷貝和淺賦值 深賦值

include includeusing namespace std class string else 淺拷貝 也就是系統預設的拷貝,可寫可不寫。string const string s 預設的拷貝構造 深拷貝 string const string s string s2 s1 深賦值 str...

賦值 淺拷貝 深拷貝

堆是動態分配記憶體,記憶體大小不一 棧是自動分配相對固定大小的記憶體空間,並由系統自動釋放 基本資料型別值是不可變的,比較是值的比較 基本資料型別,傳值。開闢乙個新的記憶體空間 js 基本資料型別,儲存在 棧 中,記憶體可以及時 引用型別值是可變的,比較是引用的比較,看其引用是否指向同乙個物件 引用...

深拷貝 淺拷貝 賦值

賦值 class teacher class student student s1 new student student s2 s1 s1 s2,指向的記憶體區域相同 拷貝 class teacher class student implement cloneable student s1 new...