深浅拷贝-简单案例说明(Python)

本文通过案例探讨Python中的深浅拷贝概念,重点分析不可变和可变数据类型在拷贝时的区别。在不可变类型中,无论深浅拷贝,变量都指向同一地址;而在可变类型如列表中,浅拷贝会因底层数据修改而受影响,深拷贝则不受影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在理解这块内容之前需要明白Python中的可变数据类型和不可变数据类型。
参考:https://blog.youkuaiyun.com/PiKeHuPu/article/details/104554268

深浅拷贝

我们通过例子来总结:

from copy import copy,deepcopy
a = 3
c = copy(a)
b = deepcopy(a)
print(id(c))
print(id(b))

结果:

140723133869888
140723133869888

我们可以看到:我们先把copy中的copy和deepcopy导入,然后a=3,之后分别用c和d来接收copy和deepcopy的返回值,打印其地址却发现他们都指向了同一块地址,并且这个地址是和a变量指向的地址是一样的,该地址存放的是3。
好了,这时:我们做出一点点修改:令a = 4

a = 3
c = copy(a)
b = deepcopy(a)
print(id(a))
print(id(c))
print(id(b))
a = 4
print(id(a))
print(id(c))
print(id(b))

我们可以得到如下结果:

140722501906240
140722501906240
140722501906240
140722501906272
140722501906240
140722501906240

观察:我们发现这时只有a变量的结果在修改后发生了改变,那么究竟是为什么?
原因:Python中数据类型有不可变数据类型,整型就属于不可变数据类型,当我们把a赋值为3时,令c和b得到其浅拷贝和深拷贝时,就相当于把c和b都指向了内存中存放3的地址。因为Python自己不需要那么多内存来存放冗余的数据,我拷贝这些文件时,无论是浅拷贝还是深拷贝,无论最终变量标识符有多少,只需要让他们都指向同一个地址就可以。
重点:因为Python在重新给存放不可变数据类型的变量重新赋值时,并不会把其指向地址的内容修改,而是重新“拿”一个新的内存出来存放新的数据。

比较1:

ls = [3, 2, 1]
c = copy(ls)
b = deepcopy(ls)
print(ls,id(ls))
print(c,id(c))
print(b,id(b))
ls[0] += 1
print(ls,id(ls))
print(c,id(c))
print(b,id(b))

结果:

[3, 2, 1] 2167612727816
[3, 2, 1] 2167612727880
[3, 2, 1] 2167633405576
[4, 2, 1] 2167612727816
[3, 2, 1] 2167612727880
[3, 2, 1] 2167633405576

如上述代码和结果:可以看出,ls时一个一维列表,c和b分别是ls的浅拷贝和深拷贝,此时,c和b以及a的地址都是不一样的。

结论1

  1. 浅拷贝和深拷贝在拷贝不可变数据类型时,变量都指向同一个地址。

  2. 浅拷贝和深拷贝在拷贝可变数据类型时,变量都指向不同的地址。

  3. 在拷贝可变数据类型时,又创建了相同的新数据。

  4. 因为地址不同,所以修改ls中的数据时,深浅拷贝后得到的数据都不会改变。

比较2:

据说二维的列表就会发生一些变化了。So:
Code First:

ls = [3, 2, [4, 5]]
c = copy(ls)
b = deepcopy(ls)
print(ls,id(ls))
print(c,id(c))
print(b,id(b))
ls[2][0] = 87
print(ls,id(ls))
print(c,id(c))
print(b,id(b))

实验:我们在ls中加了一个列表,并尝试两次输出,之间尝试修改ls二位列表中的数据。这里对ls[2][0]的数据进行了修改。
结果:

[3, 2, [4, 5]] 2654706295368
[3, 2, [4, 5]] 2654727038984
[3, 2, [4, 5]] 2654707561160
[3, 2, [87, 5]] 2654706295368
[3, 2, [87, 5]] 2654727038984
[3, 2, [4, 5]] 2654707561160

现象:我们可以看到,修改ls[2][0]的值以后,深拷贝中的内容并没有发生改变,而浅拷贝中的内容发生了变化。可我们观察他们的地址并不一样,为什么呢?
解释:浅拷贝在完成操作后,只对第一层进行拷贝(我们这里把大于第一层的称为深层),换句话说,浅拷贝完整的复制了ls[i](这里表示第一层)即第一层的数据。这里c得到的是第一层,第二层被第一层所指向。所以当我们修改深层数据时,浅拷贝的内容也会跟着发生变化。
深拷贝就u不一样了,深拷贝会把所有可变数据类型都赋值一遍。(这里好好理解什么是可变数据类型)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值