一、文字說明:
在對原有列表進行操作的時候,很有可能會修改原有列表的值,所以根據需要在這之前最好先將原有列表拷貝乙份,在對它的副本進行操作,而原列表保持不變。這個時候就需要注意 如何拷貝 的問題,因為它牽扯到 對於你新拷貝出來的列表進行操作是否還是會修改原有列表的值。
通過學習,我有以下總結,對於列表一共有三種拷貝方法:
1.賦值拷貝。c=a,即通過』='號將a列表賦值給b列表。
這種列表方式要注意的是,它只是給a列表的位址新增加了乙個叫做c的標籤,也就是說a和c都指向的是同乙個列表位址,所以即便c是你拷貝後的列表,當你對c進行操作時,a也會發生一模一樣的變化。
2.通過b=a.copy()方法進行拷貝。(b=a[:]也是淺拷貝)
這種方式與第一種通過賦值進行拷貝的方式不同,它是新建了乙個位址用於存放拷貝後的列表,也就是說原列表a與通過a.copy()方式是存放在不同的位置,以我這個新手的理解,這樣的話,a與b可能從此就各自安好,各司其職 互不干擾了吧。 然而,世界遠比想象中的複雜。是的,測試了好多次,確實對於原列表進行操作後,新拷貝的列表都沒有發生變化。
但是!有乙個特殊的情況:如果,原列表中包含列表元素,一旦原列表中的該列表元素發生了變化,則通過copy方法得到的列表中該元素也會發生一樣的變化。
通過網上查閱資料,我的理解是,當原列表a中巢狀有其他列表ls時,這個作為原列表中乙個元素的巢狀列表ls,他自己有乙個自己的位址,而原列表a的位址只是對ls的位址進行了引用,通過copy雖然新建了乙個列表位址,但這個列表位址中對於巢狀列表ls的位址也只是複製了其引用,所以ls的位址作為乙個單獨的存在被原列表和copy複製後的列表b同時引用,所以當乙個變時,兩個都會發生變化。
那麼就沒有辦法通過拷貝,來形成乙個新的列表,還確保它自此以後和原列表沒有任何關係了嗎?
不是的。
3.通過import copy,使用copy.deepcopy(list),通過它來實現拷貝後原列表和新列表徹底無關係。
copy.deepcopy(list)是對原列表的全部的拷貝,連同他巢狀的列表的位址也一起進行了拷貝,而不像ls.copy()拷貝的只是他的引用。所以自此,原列表和新複製的列表無關了。
不知道理解的對不,還需要大家的檢驗和後續不斷的反思
二、**說明:
1.關於賦值=拷貝的**說明:
>>
> a=[1
,2,3
,['boy'
,'girl']]
>>
> b=a
>>
> a.
(10000
)>>
> a[1
,2,3
,['boy'
,'girl'],
10000
]>>
> b[1
,2,3
,['boy'
,'girl'],
10000
]>>
>
id(a)
4318318464
>>
>
id(b)
4318318464 #可以看出通過賦值=拷貝的列表和原列表位址一致,所以之後原列表和新列表也會一起變
>>
> a[3]
.(11111
)>>
> a[1
,2,3
,['boy'
,'girl'
,11111],
10000
]>>
> b[1
,2,3
,['boy'
,'girl'
,11111],
10000
]>>
>
id(a[3]
)4318317504
>>
>
id(b[3]
)4318317504 #可以看出原列表中巢狀的列表[
'boy'
,'girl'
,11111
]和新列表中的[
'boy'
,'girl'
,11111
]元素的位址是一樣的
2.關於a.copy()方法的**說明:
>>> a
[1, 2, 3, ['name', 'boy', 'girl']]
>>> c=a.copy()
>>> c
[1, 2, 3, ['name', 'boy', 'girl']]
>>> a
[1, 2, 3, ['name', 'boy', 'girl']]
>>> id(a[3])
4335438720
>>> id(c[3])
4335438720
# 這裡可以看出,通過a.copy()複製的列表中巢狀的列表['name', 'boy', 'girl'] 的位址與原列表中巢狀的['name', 'boy', 'girl']的位址一樣。都是4335438720
>>> id(a[0])
4315287600
>>> id(c[0])
4311550608 #這裡看出 對於原列表中其他非巢狀的元素,新舊兩個列表的位址是不一樣的。
>>> a.insert(0,'new')
>>> a
['new', 1, 2, 3, ['name', 'boy', 'girl']]
>>> c
[1, 2, 3, ['name', 'boy', 'girl']] #對原列表中加入新的元素,新複製的列表並沒有改變
>>> a[4].insert(0,'sun')
>>> a
['new', 1, 2, 3, ['sun', 'name', 'boy', 'girl']]
>>> c
[1, 2, 3, ['sun', 'name', 'boy', 'girl']] #由於新舊列表中巢狀的列表['name', 'boy', 'girl'] 的位址一樣,對列表中巢狀的列表進行修改時,新舊列表同時被修改。(都加入了'sun')
3.通過import copy,使用copy.deepcopy(list)進行深拷貝
>>
> a=[1
,2,3
,['boy'
,'girl']]
>>
> import copy
>>
> d=copy.
deepcopy
(a)>>
> a[1
,2,3
,['boy'
,'girl']]
>>
> d[1
,2,3
,['boy'
,'girl']]
>>
>
id(a[3]
)4335438720
>>
>
id(d[3]
)4318327808 #從這看出來 原列表 a 和 通過copy.
deepcopy
(a)得到的新列表d雖然看起來一模一樣,但是他們內嵌的列表[
'boy'
,'girl'
]的位址並不一樣。
>>
> a[3]
.insert(0
,'name'
)>>
> a[1
,2,3
,['name'
,'boy'
,'girl']]
>>
> d[1
,2,3
,['boy'
,'girl'
]] #對a的操作並沒有影響d.
>>
>
87907221
js 淺拷貝直接賦值 js的賦值與淺拷貝 深拷貝
昨天翻了下陣列api,看到concat和slice方法,突然想到這個兩個方法是淺拷貝還是深拷貝,結果陷入了死胡同,為什麼mdn文件說是淺拷貝,但進行簡單的操作為什麼能複製成功啊,糾結半天後才弄清原由,原來我一直把賦值和深淺拷貝搞混了。首先不要把引用型別的賦值歸結為淺拷貝,深拷貝和淺拷貝只針對像 ob...
Python 列表賦值 淺拷貝 深拷貝 02
關於python中列表 字典的深淺拷貝問題之前認識比較模糊,之前的筆記中其實只是區分了拷貝和賦值的問題,今天以列表為例重新學習一下 關於深淺拷貝和賦值的概念 a.直接賦值 用等號 其實就是物件的引用 b.淺拷貝 用copy 拷貝父物件,但是不會拷貝內部子物件 c.深度拷貝 用deepcopy,是採用...
Python 賦值 淺拷貝 深拷貝
賦值 a b,只拷貝了物件的引用,沒有拷貝內容。兩個物件的id一樣 淺拷貝 copy.copy 構造乙個新的復合物件,然後將子物件引用插入到原始物件的副本中。深拷貝 copy.deepcopy 構造乙個新的復合物件,然後遞迴地將子物件副本插入原始物件的副本。給個栗子 從這個栗子可以看出,對c進行修改...