在Python中,常常要對一個list進行復制。對於複製,天然的就有深拷貝與淺拷貝問題。深拷貝與淺拷貝的區別在於,當從本來的list複製出的list以後,修改其中的任意一個是否會對另外一個形成影響,即這兩個list在內存中是否儲存在同一個區域,這也是區分深拷貝與淺拷貝的重要依據。接下來咱們就針對Python中list複製的幾種方法,來探究一下其是屬於深拷貝仍是淺拷貝。弄清楚這個問題,有助於咱們在編程中規避錯誤,減小沒必要要的調試時間。編程
若是用=直接賦值,是非拷貝方法。這兩個列表是等價的,修改其中任何一個列表都會影響到另外一個列表。這也是Python做爲動態語言與C這類靜態語言在思想上的不一樣之處。安全
old = [1,[1,2,3],3] new = old print('Before:') print(old) print(new) new[0] = 3 new[1][0] = 3 print('After:') print(old) print(new)
運行結果以下:app
咱們來看如下代碼:spa
old = [1,[1,2,3],3] new = old.copy() print('Before:') print(old) print(new) new[0] = 3 new[1][0] =3 print('After:') print(old) print(new)
運行結果以下:調試
對於list的第一層,是實現了深拷貝,但對於嵌套的list,仍然是淺拷貝。這其實很好理解,內層的list保存的是地址,複製過去的時候是把地址複製過去了。嵌套的list在內存中指向的仍是同一個。 code
使用列表生成式產生新列表也是一個淺拷貝方法,只對第一層實現深拷貝。blog
old = [1,[1,2,3],3] new = [i for i in old] print('Before') print(old) print(new) new[0] = 3 new[1][0] = 3 print('After') print(old) print(new)
運行結果以下:內存
經過for循環遍歷,將元素一個個添加到新列表中。這也是一個淺拷貝方法,只對第一層實現深拷貝。for循環
old = [1,[1,2,3],3] new = [] for i in range(len(old)): new.append(old[i]) print('Before:') print(old) print(new) new[0] = 3 new[1][0] = 3 print('After:') print(old) print(new)
運行結果以下:class
4.使用切片
經過使用[:]切片,能夠淺拷貝整個列表。一樣的,只對第一層實現深拷貝。
old = [1,[1,2,3],3] new = old[:] print('Before:') print(old) print(new) new[0] = 3 new[1][0] = 3 print('After:') print(old) print(new)
運行結果以下:
若是用deepcopy()方法,則不管多少層,不管怎樣的形式,獲得的新列表都是和原來無關的,這是最安全最清爽最有效的方法。
使用時,要導入copy。
import copy old = [1,[1,2,3],3] new = copy.deepcopy(old) print('Before:') print(old) print(new) new[0] = 3 new[1][0] = 3 print('After:') print(old) print(new)
運行結果以下: