1. 程式人生 > >python的列表復制詳解

python的列表復制詳解

查看 ado () 操作 修改 硬鏈接 引用 linux clas

非復制但內容一致的情況

首先生成列表list1,list2,查看其中內容,對內容做比較,對內存id做比較:

list1 = list(range(5))
list2 = list(range(5))
print(list1)
print(list2)
print(list1 == list2)
print("list1 ID:",id(list1))
print("list2 ID:",id(list2))

輸出結果為:

[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
True
list1 ID: 2402197214728
list2 ID: 2402197214856

依輸出結果可見,兩個列表只是都叠代了range(5),內容一致,但內存地址不同,
相互獨立。

列表賦值復制

生成列表list1,將list3賦值等於list1,對內容做比較,對內存id做比較:

list1 = list(range(5))
list3 = list1
list3[1] = 8
print(list3)
print(list1)
print("list1 ID:",id(list3))
print("list2 ID:",id(list1))

輸出結果為:

[0, 8, 2, 3, 4]
[0, 8, 2, 3, 4]
list1 ID: 2439749211784
list2 ID: 2439749211784

依輸出結果可見,當list3賦值等於list1時,當對任意一列表進行修改時,另外一個列表同時被修改,原因是兩個列表所調用的內存地址相同,兩個入口同時指向同一內存地址,與linux文件系統的硬鏈接相似。

for循環叠代追加復制

生成空列表list4,將list2中的內容使用for循環叠代追加至list4,對內容做比較,對內存id做比較:

list2 = list(range(5))
list4 = []

for _ in list2:
    list4.append(_)

print(list2)
print(list4)
print(list2 == list4)
print("list2 ID:",id(list2))
print("list4 ID:",id(list4))

輸出結果為:

[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
True
list2 ID: 
1698948945544 list4 ID: 1698948944392

依輸出結果可見,for循環叠代復制後的list4和list2內容一致,但內存地址不同,list只是復制了list2中的內容,但兩者相互獨立。

列表的淺copy復制(shadow copy)

將列表list6對list5進行淺copy,對內容做比較,對內存id做比較:

list5 = [1,2,"qwer",[5,6]]

list6 = list5.copy()

print(list5)
print(list6)
print(list5 == list6)
print("list5 ID:",id(list5))
print("list6 ID:",id(list6))

list5[3][0] = asdf
print(list5)
print(list6)
print(id(list5[-1]))
print(id(list6[-1]))

輸出結果為:

[1, 2, qwer, [5, 6]]
[1, 2, qwer, [5, 6]]
True
list5 ID: 3016971798152
list6 ID: 3016972669320
[1, 2, qwer, [asdf, 6]]
[1, 2, qwer, [asdf, 6]]
3016972669448
3016972669448

依輸出結果可見,list6對list5 進行淺copy後,兩個列表內容一致,內存地址不相同。但當對list5中的引用類型進行修改後,list6中的同時也被修改了,原因是進行淺copy操作後,list6和list5的引用類型內存地址一樣,所以對list5修改時,list6也被修改。

列表的深copy復制

將列表list7對list8進行深copy,需要import copy模塊。對內容做比較,對內存id做比較:

import copy

list7 = [1,2,"qwer",[5,6]]

list8 = copy.deepcopy(list7)

print(list7)
print(list8)
print(list7 == list8)
print("list7 ID:",id(list7))
print("list8 ID:",id(list8))

list7[3][0] = asdf
print(list7)
print(list8)
print(id(list7[-1]))
print(id(list8[-1]))

輸出結果為:

[1, 2, qwer, [5, 6]]
[1, 2, qwer, [5, 6]]
True
list7 ID: 1797818246088
list8 ID: 1797818247368
[1, 2, qwer, [asdf, 6]]
[1, 2, qwer, [5, 6]]
1797818245896
1797818247304

依輸出結果可見,list8對list7進行深copy後,兩個列表內容一致,內存地址不相同。當對list7中的引用類型進行修改後,list8並沒有被修改,list7和list8的引用類型內存地址不一樣。list7和list8內容一致,但完全獨立。

如果想讓copy對象與原列表真正的完全不同,就需要用到深copy

python的列表復制詳解