Python中list的複製及深拷貝與淺拷貝探究

  在Python中,常常要對一個list進行復制。對於複製,天然的就有深拷貝與淺拷貝問題。深拷貝與淺拷貝的區別在於,當從本來的list複製出的list以後,修改其中的任意一個是否會對另外一個形成影響,即這兩個list在內存中是否儲存在同一個區域,這也是區分深拷貝與淺拷貝的重要依據。接下來咱們就針對Python中list複製的幾種方法,來探究一下其是屬於深拷貝仍是淺拷貝。弄清楚這個問題,有助於咱們在編程中規避錯誤,減小沒必要要的調試時間。編程

1、非拷貝方法——直接賦值

  若是用=直接賦值,是非拷貝方法。這兩個列表是等價的,修改其中任何一個列表都會影響到另外一個列表。這也是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

2、淺拷貝的幾種方法

1.copy()方法

  咱們來看如下代碼: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

2.使用列表生成式

  使用列表生成式產生新列表也是一個淺拷貝方法,只對第一層實現深拷貝。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)

運行結果以下:內存

 

3.用for循環遍歷

  經過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)

運行結果以下:

 

3、深拷貝的實現

  若是用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)

運行結果以下:

相關文章
相關標籤/搜索