深淺copy——Python

在python中,由於共享內存導致copy有深copy和淺copy之分,大家稍有不注意就可能會改變不希望被改變的信息。

淺copy

數據“半共享”

  1. 可以淺copy的數據類型:list、dict、set
    Q:何爲淺copy?
    A:只能copy最淺層(即第一層),不能copy數據類型中嵌套的數據類型

在python 中 id()方法可以查看存放變量的內存地址,這爲我們下面理解深淺copy提供了便利。
不多說,上碼:

>>> a = [1,[23,4],3]
>>> a
[1, [23, 4], 3]
>>> b = a.copy()
>>> b
[1, [23, 4], 3]
>>> b[0]=2
>>> b
[2, [23, 4], 3]
>>> a
[1, [23, 4], 3]
>>> b[1][1]=234234		#更改列表中嵌套的二級列表
>>> b
[2, [23, 234234], 3]
>>> a					#原列表也會被更改
[1, [23, 234234], 3]
>>> id(a)
2198613584328
>>> id(b)
2198613596744
>>> id(a[0])
140710427074960
>>> id(b[0])
140710427074992			#對於改變的元素,地址也會變
>>> id(b[1])
2198613584904			#b中嵌套的二級列表地址
>>> id(a[1])
2198613584904			#原列表中嵌套的二級列表地址,可看出和copy的地址一致
>>> id(a[2])			
140710427075024	
>>> id(b[2])
140710427075024			#對於沒有改變的元素,地址與原列表地址一致

從代碼可以看出:改變b中嵌套的二級列表會影響a中的二級列表。
Q:爲什麼二級列表裏的數值被更改了?
A:淺copy時,內存會開闢一個新的空間存放一個新的列表,列表中的元素和元素地址都會被copy過來,但可變數據類型(二級列表)被當做一個整體不被copy,所以二級列表的地址也和原列表的地址保持一致,即對二級列表中的元素更改時,a和b會相互影響,元素永遠相同。
而一級列表中的不可變數據類型,雖然元素與地址都被複制過來,但兩者進行修改時不會相互影響,並且修改後地址會變得不一致。而在一級列表添加新的元素時,兩者同樣不會相互影響,只要不改變copy過來的元素,地址會一直與copy過來的一致。
dict和set也是如此。


深copy

copy所有內容。深copy後改變其內容不會對原數據產生任何影響。


深copy需要導入python自帶的庫——copy。
上碼:

>>> import copy
>>> a = [1,[23,4],3]
>>> b = copy.deepcopy(a)
>>> b
[1, [23, 4], 3]
>>> b[0] = 2
>>> b
[2, [23, 4], 3]
>>> a
[1, [23, 4], 3]
>>> b[1][1] = 234234
>>> b
[2, [23, 234234], 3]
>>> a
[1, [23, 4], 3]
>>> id(a)
2198613756168
>>> id(b)
2198613785864
>>> id(a[0])
140710427074960
>>> id(b[0])
140710427074992			#對於改變的元素,地址會改變
>>> id(a[1])
2198613756744			#原列表中嵌套的二級列表地址
>>> id(b[1])
2198613785288			#b中嵌套的二級列表地址,可看出和原列表中嵌套的二級列表地址不一致
>>> id(a[2])
140710427075024
>>> id(b[2])
140710427075024			#對於沒有改變的元素,地址與原列表地址一致

從代碼可以看出:a,b互不影響。

淺析深淺copy

深copy是拷貝所有內容。包括內部(二級列表)的所有,形成一個新的對象,雖然與之前的值和內容一模一樣,但是它們時完完全全的兩個對象,二級列表的地址同樣被拿出來存在新的內存當中,地址同樣會不一樣,所以做出改變時不會相互影響;其它與淺copy一致,不可變數據類型改變時不會相互影響,且改變後地址會發生改變。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章