python中的深拷貝和淺拷貝理解

在python中,對象賦值實際上是對象的引用。當創建一個對象,然後把它賦給另一個變量的時候,python並沒有拷貝這個對象,而只是拷貝了這個對象的引用。以下分兩個思路來分別理解淺拷貝和深拷貝:

  • 利用切片操作和工廠方法list方法拷貝
  • 利用copy中的deepcopy方法進行拷貝

1、利用切片操作和工廠方法list方法拷貝

代碼場景:有一個小夥jack,tom通過切片操作拷貝jack,anny通過工廠方法拷貝jack。

>>> jack = ['jack', ['age', 20]]
>>> tom = jack[:]
>>> anny = list(jack)

來看下三者的id值:

>>> print id(jack), id(tom), id(anny)
144846988 144977164 144977388

從id值來看,三者是不同的對象。爲tom和anny重新命名爲各自的名稱:

>>> tom[0] = 'tom'
>>> anny[0] = 'anny'
>>> print jack, tom, anny
['jack', ['age', 20]] ['tom', ['age', 20]] ['anny', ['age', 20]]

從這裏來看一切正常,可是anny只有18歲,重新爲anny定義歲數。

>>> anny[1][1] = 18
>>> print jack, tom, anny
['jack', ['age', 18]] ['tom', ['age', 18]] ['anny', ['age', 18]]

這時候奇怪的事情發生了,jack、tom、anny的歲數都發生了改變,都變成了18了。jack、tom、anny他們應當都是不同的對象,怎麼會互相影響呢?看下jack,tom,anny的內部元素每個元素id:

>>> [id(x) for x in jack]
[3073896320L, 3073777580L]
>>> [id(x) for x in tom]
[144870744, 3073777580L]
>>> [id(x) for x in anny]
[144977344, 3073777580L]

恍然大悟,原來jack、tom、anny的歲數元素指向的是同一個元素。修改了其中一個,當然影響其他人了。那爲什麼修改名稱沒影響呢?原來在python中字符串不可以修改,所以在爲tom和anny重新命名的時候,會重新創建一個’tom’和’anny’對象,替換舊的’jack’對象。爲了便於理解,我畫了一個草圖:

python淺拷貝圖解

python淺拷貝圖解

2、利用copy中的deepcopy方法進行拷貝

爲了讓他們之間不互相影響,用deepcopy來試試

>>> jack = ['jack', ['age', '20']]
>>> import copy
>>> tom = copy.deepcopy(jack)
>>> anny = copy.deepcopy(jack)

根據第一個思路進行重命名,重定歲數操作:

>>> tom[0] = 'tom'
>>> anny[0] = 'anny'
>>> print jack, tom, anny
['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', '20']]
>>> anny[1][1] = 18
>>> print jack, tom, anny
['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', 18]]

這時候他們之間就不會互相影響了。打印出每個人的內部元素每個id:

>>> [id(x) for x in jack]
[139132064, 3073507244L]
>>> [id(x) for x in tom]
[139137464, 139132204]
>>> [id(x) for x in anny]
[139141632, 139157548]

他們的內部元素也都指向了不同的對象。

小結:

思路一:利用切片操作和工廠方法list方法拷貝就叫淺拷貝,只是拷貝了最外圍的對象本身,內部的元素都只是拷貝了一個引用而已。

思路二:利用copy中的deepcopy方法進行拷貝就叫做深拷貝,外圍和內部元素都進行了拷貝對象本身,而不是引用。

但是對於數字,字符串和其他原子類型對象等,沒有被拷貝的說法,即便是用深拷貝,查看id的話也是一樣的,如果對其重新賦值,也只是新創建一個對象,替換掉舊的而已。

轉載請註明:快樂編程 » python中的深拷貝和淺拷貝理解

發佈了209 篇原創文章 · 獲贊 76 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章