深浅copy——Python

深copy和浅copy

在python中,由于共享内存导致copy有深copy和浅copy之分,大家稍有不注意就可能会改变不希望被改变的信息。

浅copy

数据“半共享”

  1. 可以浅copy的数据类型:list、dict、set
    Q:何为浅copy?
    A:只能copy最浅层(即第一层),不能copy数据类型中嵌套的数据类型

在python 中 id()方法可以查看存放变量的内存地址,这为我们下面理解深浅copy提供了便利。
不多说,上码:

>>> a = [1,[23,4],3]
>>> a
[1, [23, 4], 3]
>>> b = a.copy()
>>> b
[1, [23, 4], 3]
>>> b[0]=2
>>> b
[2, [23, 4], 3]
>>> a
[1, [23, 4], 3]
>>> b[1][1]=234234		#更改列表中嵌套的二级列表
>>> b
[2, [23, 234234], 3]
>>> a					#原列表也会被更改
[1, [23, 234234], 3]
>>> id(a)
2198613584328
>>> id(b)
2198613596744
>>> id(a[0])
140710427074960
>>> id(b[0])
140710427074992			#对于改变的元素,地址也会变
>>> id(b[1])
2198613584904			#b中嵌套的二级列表地址
>>> id(a[1])
2198613584904			#原列表中嵌套的二级列表地址,可看出和copy的地址一致
>>> id(a[2])			
140710427075024	
>>> id(b[2])
140710427075024			#对于没有改变的元素,地址与原列表地址一致

从代码可以看出:改变b中嵌套的二级列表会影响a中的二级列表。
Q:为什么二级列表里的数值被更改了?
A:浅copy时,内存会开辟一个新的空间存放一个新的列表,列表中的元素和元素地址都会被copy过来,但可变数据类型(二级列表)被当做一个整体不被copy,所以二级列表的地址也和原列表的地址保持一致,即对二级列表中的元素更改时,a和b会相互影响,元素永远相同。
而一级列表中的不可变数据类型,虽然元素与地址都被复制过来,但两者进行修改时不会相互影响,并且修改后地址会变得不一致。而在一级列表添加新的元素时,两者同样不会相互影响,只要不改变copy过来的元素,地址会一直与copy过来的一致。
dict和set也是如此。


深copy

copy所有内容。深copy后改变其内容不会对原数据产生任何影响。


深copy需要导入python自带的库——copy。
上码:

>>> import copy
>>> a = [1,[23,4],3]
>>> b = copy.deepcopy(a)
>>> b
[1, [23, 4], 3]
>>> b[0] = 2
>>> b
[2, [23, 4], 3]
>>> a
[1, [23, 4], 3]
>>> b[1][1] = 234234
>>> b
[2, [23, 234234], 3]
>>> a
[1, [23, 4], 3]
>>> id(a)
2198613756168
>>> id(b)
2198613785864
>>> id(a[0])
140710427074960
>>> id(b[0])
140710427074992			#对于改变的元素,地址会改变
>>> id(a[1])
2198613756744			#原列表中嵌套的二级列表地址
>>> id(b[1])
2198613785288			#b中嵌套的二级列表地址,可看出和原列表中嵌套的二级列表地址不一致
>>> id(a[2])
140710427075024
>>> id(b[2])
140710427075024			#对于没有改变的元素,地址与原列表地址一致

从代码可以看出:a,b互不影响。

浅析深浅copy

深copy是拷贝所有内容。包括内部(二级列表)的所有,形成一个新的对象,虽然与之前的值和内容一模一样,但是它们时完完全全的两个对象,二级列表的地址同样被拿出来存在新的内存当中,地址同样会不一样,所以做出改变时不会相互影响;其它与浅copy一致,不可变数据类型改变时不会相互影响,且改变后地址会发生改变。

发布了2 篇原创文章 · 获赞 23 · 访问量 810

猜你喜欢

转载自blog.csdn.net/Viking_JoneJi/article/details/105494407