Python的賦值、淺拷貝、深拷貝


在寫dict數據類型時,有提到過「賦值語句」與copy()函數。
其實說到深淺拷貝,須要考慮具體的數據類型。一部分是不可變對象,如數字、字符串;另外一部分是可變對象,如列表、字典等。函數


1、定義解釋

  • 變量:一個系統表的元素,指向對象的鏈接空間。
  • 對象:被分配的一塊內存,存儲其實際的值。
  • 引用:從變量到對象的指針。
  • 不可變對象:一旦建立就不能夠修改,如數字、字符串、元組。
  • 可變對象:能夠修改的對象,如列表、字典。
  • 賦值:經過語句「=」實現。左邊是新建的變量,右邊能夠是直接內容,或者已存在的變量。是對象的引用,Python沒有拷貝該對象,只是拷貝了對象的引用,新變量指向源變量內存地址。
  • 淺拷貝:對一個對象進行拷貝。拷貝最外圍的對象自己,內部的元素都只是拷貝了一個引用而已。即新建立了一個類型跟原對象同樣、內容是原對象的引用。【淺拷貝對象是新的,對象的引用內容是舊的。】
    淺拷貝實現的幾種方式:(1)切片:[:];(2)工廠函數,好比list()、dict();(3)使用copy()。
  • 深拷貝:外圍和內部元素都進行了拷貝對象自己,而不是引用。即把對象複製一遍,而且該對象中引用的其餘對象也複製。

2、不可變對象

對於不可變對象,例如數字和字符串而言,賦值(=)、淺拷貝(copy())和深拷貝(deepcopy())沒有區別,由於他們的對象引用永遠指向同一個內存地址。
經過例子演示:spa

>>> var_1 = 123
>>> id(var_1)            # 經過id()查看地址
1615552144
>>> var_2 = var_1
>>> id(var_2)
1615552144
>>>
>>> import copy        # 淺、深拷貝須要導入copy模塊
>>> var_3 = copy.copy(var_1)
>>> id(var_3)
1615552144
>>>
>>> var_4 = copy.deepcopy(var_1)
>>> id(var_4)
1615552144

你會發現var_1 ~ var_4 的id指向是同樣的。指針

3、可變對象

對list、dict等數據類型而言,賦值、淺拷貝和深拷貝,他們對內存地址的變化是不一樣的。
賦值淺拷貝:值相等,地址相等;
copy淺拷貝:值相等,地址不相等;
deepcopy深拷貝:值相等,地址不相等;code

例子一:
base[0]=’name’,是一個string,不可變對象;base[1]=[‘age’,18],是list,可變對象。
base_一、base_2均是base的淺拷貝,三者id()同樣。
當對第一個string元素進行不一樣的更改時,發現id各不相同,不會互相影響,由於字符串(不可變)被顯示的拷貝,當修改後,新建立了一個字符對象。
而修改第二個list元素時,不一樣的修改都只對最後一次修改生效,且互相影響,由於第二個元素列表只是簡單的複製了其引用,修改任何一個淺拷貝,都會修改引用的內容。
clipboard.png對象

例子二:深拷貝
建立一個字典對象,並使用深拷貝建立一個新的對象。ip

>>>import copy
>>> var = {"a":1,"b":2,"c":[3,'abc']}
>>> var1 = copy.deepcopy(var)
>>> id(var),id(var1)
(17616992, 15671136)            # 地址不相同
>>> id(var['c']),id(var1['c'])
(15695144, 15695384)        
>>> id(var['c'][0]),id(var1['c'][0])
(1615550224, 1615550224)        # ‘c’元素的內存地址是相同的
>>>
>>> var1['c'][0] = 4
>>> var
{'a': 1, 'b': 2, 'c': [3, 'abc']}
>>> var1
{'a': 1, 'b': 2, 'c': [4, 'abc']}
>>> id(var['c'][0]),id(var1['c'][0])
(1615550224, 1615550240)        # 對var1的修改沒有影響var

❤ thanks for watching, keep on updating...

相關文章
相關標籤/搜索