1. 程式人生 > >Python 列表深淺複製詳解

Python 列表深淺複製詳解

在文章《Python 資料型別》裡邊介紹了列表的用法,其中列表有個 copy() 方法,意思是複製一個相同的列表。例如

1 names = ["小明", "小紅", "小黑", "小黃", "小白"]
2 # 把 names 複製,賦值給 names2 變數
3 names2 = names.copy()
4 # 分別輸出 names names2
5 print(names)
6 print(names2)

這時會發現結果是一樣的,那麼問題來了,我要把 names 列表中的 小黃改成英文 Yellow,那麼 names2 的小黃會發生變化嗎?寫一段程式碼看看

複製程式碼
1 names = ["
小明", "小紅", "小黑", "小黃", "小白"] 2 # 把 names 複製,賦值給 names 變數 3 names2 = names.copy() 4 # 修改 names 列表中的 小黃 5 names[3] = "Yellow" 6 # 分別輸出 names names2 7 print(names) 8 print(names2)
複製程式碼

看結果會發現,只是把names 列表中的 小黃 改成了 Yellow ,names2 列表中沒有變,其實它的原理很簡單,如下圖

首先,names 指向一個列表,然後把 names 複製了一份,賦值給 names2 ,由於 修改的是 第一個 列表的 小黃,所以第二個列表不受影響。

那麼現在我改一下這個列表,從names列表中再新增一個列表,如下程式碼

複製程式碼
1 names = ["小明", "小紅", ["張三", "李四", "王五"], "小黑", "小黃", "小白"]
2 # 複製一份列表
3 names2 = names.copy()
4 # 把李四 改成英文
5 names[2][1] = "Lisi"
6 print(names)
7 print(names2)
複製程式碼

這段程式碼的執行結果是,兩個列表的李四都變成了英文,來分析一下原理

其實這個圖也挺簡單的,就是中間那個列表是單獨分配了一塊空間,然後從第一層列表中去引用地址,複製的names2 也是引用的地址,所以真實的值一變,兩個列表的內部列表的值也就變了。

也就是說 list.copy() 方法只能 copy 一層,這就是所謂的淺複製。

 補充:第二個列表copy 第一個列表,實際上第二個列表的每個元素是第一個列表每個元素的引用

實現淺複製的三種方法

複製程式碼
1 import copy
2 
3 names = ["小明", "小紅", "小黑", "小黃", "小白"]
4 # 淺copy 1.
5 names1 = copy.copy(names)
6 # 2.
7 names2 = names[:]
8 # 3. 工廠函式
9 names3 = list(names)
複製程式碼

深複製的方法

複製程式碼
 1 import copy
 2 
 3 names = ["小明", "小紅", "小黑", ["粉色"], "小黃", "小白"]
 4 # 深複製
 5 deep_names = copy.deepcopy(names)
 6 # 修改粉色為 Pink
 7 names[3][0] = "Pink"
 8 # 分別列印輸出兩個列表
 9 print(names)
10 print(deep_names)
複製程式碼

輸出結果為:

['小明', '小紅', '小黑', ['Pink'], '小黃', '小白']
['小明', '小紅', '小黑', ['粉色'], '小黃', '小白']