1. 程式人生 > >python列表中的深淺copy

python列表中的深淺copy

其中 tro 深淺copy 介紹 而不是 display 改變 和平 python

列表中的賦值和平常的賦值是不一樣的,看下面的代碼:
In [1]: a = 1
 
In [2]: b = a
 
In [3]: a
Out[3]: 1
 
In [4]: b
Out[4]: 1
 
In [5]: id(a)
Out[5]: 4452948992
 
In [6]: id(b)
Out[6]: 4452948992
 
In [7]: id(1)
Out[7]: 4452948992
 
In [8]: a = 4
 
In [9]: b
Out[9]: 1
 
In [10]: id(a)
Out[10]: 4452949088
 
In [11]: id(b)
Out[
11]: 4452948992 In [12]: id(1) Out[12]: 4452948992
在這段代碼中,a = 1,a指向內存地址;b = a,b也指向內存地址1,所以當a指向內存地址4的時候,b的值不變,因為b指向的內存地址是1而不是a。 在列表中就不一樣了,下面介紹列表的深淺copy 1.直接賦值
In [1]: li = [1,2,3]
 
In [2]: n = li
 
In [3]: li
Out[3]: [1, 2, 3]
 
In [4]: n
Out[4]: [1, 2, 3]
 
In [5]: li[0] = a
 
In [6]: li
Out[
6]: [a, 2, 3] In [7]: n Out[7]: [a, 2, 3] In [8]: id(li) Out[8]: 4342626376 In [9]: id(n) Out[9]: 4342626376 In [10]: id([1,2,3]) Out[10]: 4440762824
可以看出,在列表中,n是指向了li的內存地址, 不是列表[1,2,3]了,所以li的值變化的話,n也跟著變化。可以想象成li和n都指向了一個水杯,水杯裏有三塊白糖,把其中一塊換成了黑糖,
那不管是用li還是n,水杯裏現在都是有兩塊白糖和一塊黑糖。 2.淺copy
In [1]: li2 = [1,2,3,[
alex,27]] In [2]: n2 = li2.copy() In [3]: li2 Out[3]: [1, 2, 3, [alex, 27]] In [4]: n2 Out[4]: [1, 2, 3, [alex, 27]] In [5]: id(li2),id(n2) Out[6]: (4536317192, 4536271560) In [6]: li2[0] = a In [7]: li2 Out[7]: [a, 2, 3, [alex, 27]] In [8]: n2 Out[8]: [1, 2, 3, [alex, 27]] In [9]: id(li2[0]),id(n2[0]) Out[9]: (4509371784, 4506651648)
兩個列表的內存地址(id)是一樣的,但是當li2裏面的元素改變後,n2裏的元素並沒有改變,等於是只把列表(杯子)copy過去了,沒有把列表裏的元素(糖塊)copy過去,裏面的元素(糖塊)不是共享的。改裏面的元素就和最一開始說的a=1,b=a,a=5一樣的.li[0]指向了別的內存地址,n2[0]還是指向1,所以內存地址就不一樣了。 下面就不一樣了
In [10]: li2[3][0] = 帥哥
 
In [11]: li2
Out[11]: [a, 2, 3, [帥哥, 27]]
 
In [12]: n2
Out[12]: [1, 2, 3, [帥哥, 27]]
 
In [13]: id(li2[3]),id(n2[3])
Out[13]: (4536316872, 4536316872)
 
In [15]: id(li2[3][0])
Out[15]: 4536362680    # 和li2[3]的內存地址不一樣
li2[3]和li2[3][0]的內存地址並不一樣。 原因是li2[3]指的是整個列表([‘帥哥‘, 27],就當做大杯子裏的小杯子),這等於只是copy了小杯子的內存地址,裏面的東西(元素)還是共享的,也就是li2和n2共享這個小列表裏面的內容。 4.深copy(不太常用)
In [1]: import copy
 
In [2]: li3 = [1,2,3,[alex,27]]
 
In [3]: n3 = copy.deepcopy(li3)
 
In [4]: li3
Out[4]: [1, 2, 3, [alex, 27]]
 
In [5]: n3
Out[5]: [1, 2, 3, [alex, 27]]
 
In [6]: li3[3][0] = 帥哥
 
In [7]: li3
Out[7]: [1, 2, 3, [帥哥, 27]]
 
In [8]: n3
Out[8]: [1, 2, 3, [alex, 27]]
可以看出,等於是完全copy了一份,除非特殊場景這個方法不常用,也不建議用,因為如果列表存的數據量特別大的話,這樣深copy一份直接翻一倍,浪費空間。

python列表中的深淺copy