python列表中的深浅copy

Posted 梁少华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python列表中的深浅copy相关的知识,希望对你有一定的参考价值。

列表中的赋值和平常的赋值是不一样的,看下面的代码:
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的主要内容,如果未能解决你的问题,请参考以下文章

Python深浅copy

Python学习————深浅copy

python 列表深浅copy 及相关操作

python之旅 1-29 补充内容,深浅copy

Python 深浅拷贝 (Shallow copy and Deep copy in Python)

Python的深浅copy