Python学海无涯路【第19回】:深浅拷贝


1、数据在内存中的存储(一级指针)

指针 是C++中的概念,为了方便讲清楚深浅拷贝,暂借C++中的术语。

a=1
b=a

变量a和变量b在内存中的存储如下图:
在这里插入图片描述
此时若要修改变量a或变量b的值,假设修改a的值

a=2

编译器在栈中分配一块内存,存储2,假设地址为0002,如下图:
如果没有变量指向地址:0001,编译器会自动释放掉地址0001占用的内存,这里变量b还在指向地址0001,故没有被释放。
在这里插入图片描述
我们用一段程序来验证上面的解释:

a=1
b=a
print("a的内存地址:%s" %id(a))  #打印a的内存地址
print("b的内存地址:%s" %id(b))  #打印b的内存地址
a=2
print("a的内存地址:%s" %id(a))  #打印a的内存地址
print("b的内存地址:%s" %id(b))  #打印b的内存地址

输出:
a的内存地址:1747676640
b的内存地址:1747676640
a的内存地址:1747676672
b的内存地址:1747676640

2、数据在内存中的存储(多级指针)

a=[[1,2],3,4]
b=a

变量a和变量b在内存中的存储大致如下图:
在这里插入图片描述
此时,如果修改a中的元素或者b中的元素都会同时引起a、b变化,这就是下文中所要提到的浅拷贝

下面用代码验证上面的解释:

a=[[1,2],3,4]
b=a
b[1]=33		#a[1]和b[1]会同时被修改成33
print(a)
print(b)

输出:
[[1, 2], 33, 4]
[[1, 2], 33, 4]

3、赋值拷贝

修改变量a的任一元素或修改变量b的任一元素,a和b的值均会一起变

a=[[1,2],3,4]
b=a
print("修改元素前a= %s" %a)
print("修改元素前b= %s" %b)
b[1]=33     #修改二级指针对应的元素,a和b的值均会变化
print("修改元素后a= %s" %a)
print("修改元素后b= %s" %b)

输出:
修改元素前a= [[1, 2], 3, 4]
修改元素前b= [[1, 2], 3, 4]
修改元素后a= [[1, 2], 33, 4]
修改元素后b= [[1, 2], 33, 4]

4、浅拷贝

浅拷贝使用copy

4.1、浅拷贝二级指针元素的影响

修改变量a的二级指针所指的元素,只有a值会变,b值不会被改变

a=[[1,2],3,4]
b=a.copy()
print("修改元素前a= %s" %a)
print("修改元素前b= %s" %b)
b[1]=33     #修改二级指针对应的元素,只有b的值会变化
print("修改元素后a= %s" %a)
print("修改元素后b= %s" %b)

输出:
修改元素前a= [[1, 2], 3, 4]
修改元素前b= [[1, 2], 3, 4]
修改元素后a= [[1, 2], 3, 4]
修改元素后b= [[1, 2], 33, 4]

4.2、浅拷贝三级指针元素的影响

修改变量a或变量b的三级指针所指的元素,a和b的值均会一起变

a=[[1,2],3,4]
b=a.copy()
print("修改元素前a= %s" %a)
print("修改元素前b= %s" %b)
b[0][0]=11    #修改三级指针对应的元素,a和b的值均会变化
print("修改元素后a= %s" %a)
print("修改元素后b= %s" %b)

输出:
修改元素前a= [[1, 2], 3, 4]
修改元素前b= [[1, 2], 3, 4]
修改元素后a= [[11, 2], 3, 4]
修改元素后b= [[11, 2], 3, 4]

5、深拷贝

深拷贝需导入import copy
深拷贝,各元素之间互不影响
copy.copy()函数是浅拷贝,与copy函数功能一致。
copy.deepcopy()函数是深拷贝

import copy
a=[[1,2],3,4]
b=copy.deepcopy(a)	#深拷贝
print("修改元素前a= %s" %a)
print("修改元素前b= %s" %b)
b[0][0]=11    #深拷贝,各变量互不影响
print("修改元素后a= %s" %a)
print("修改元素后b= %s" %b)

输出:
修改元素前a= [[1, 2], 3, 4]
修改元素前b= [[1, 2], 3, 4]
修改元素后a= [[1, 2], 3, 4]
修改元素后b= [[11, 2], 3, 4]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值