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


(一)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個不同容器裝了同樣的東西。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM