Python中的赋值、浅拷贝和深拷贝

赋值

Python中的浅拷贝和深拷贝是一个比较重要的知识点,而且面试中经常出现,这里进行一下记录。首先,需要了解“赋值”的概念。 提到赋值,我们会想到赋值操作符“=”,在Python中,我们创建一个对象,然后将对象赋值给变量,实际上是把该对象在地址空间的id地址值拷贝给变量,也就是说“赋值”操作拷贝的是对象的引用。

如下图所示:

创建整数对象5之后,将其赋值给变量a,之后变量a又赋值给变量b,因为赋值操作拷贝的是对象的引用,也就是对象id地址值,因此可以看到a,b和整数对象5具有相同的地址值。后面变量a进行新的赋值操作,变量a对应的是整数对象6的地址值;而变量b仍然对应之前的地址值。

如果,我们创建的对象是列表,不是整数对象,其中列表是可变数据类型,整数是不可变数据类型。对于可变数据类型,每次创建可变数据类型对象的时候,即使内容一样(比如列表中数据元素相同),也会在地址空间分配新的区域。如下图所示:

上图中,因为变量a和b指向同一地址空间,因此当这一地址空间存储的值改变之后,变量a和b的值均改变。

 

可变数据类型和不可变数据类型

Python中的可变数据类型是指:当该数据类型的变量值发生变化的时候,没有开辟新的内存空间,而是在原来的内存地址上进行修改。可变数据类型包括:列表,字典,集合。

Python中的不可变数据类型是指:当该数据类型的变量值发生变化的时候,原来内存中的值不变,而是会开辟一块新的内存,变量指向该新的内存地址。不可变数据类型包括:整数,浮点数,布尔值,字符串,元组。

浅拷贝

浅拷贝是对一个对象父级(外层)的拷贝,并不会拷贝子级(内部)。在拷贝的时候,需要使用到copy这一Python库。

其中,浅拷贝可以分为两种情况,第一:对象父级(外层)是可变数据类型,比如列表,浅拷贝的时候,会开辟新的内存空间。但是,该对象内部的对象不会进行拷贝。如下图所示:

变量b是可变数据类型,因此浅拷贝的时候,会为变量c开辟新的内存空间,因此变量b和c的地址不同。但是因为是浅拷贝,只会拷贝父级对象(外层),不会拷贝内层,因此内层的可变数据类型地址不会更改。所以变量c中第4个元素的地址就是变量a对应的地址;当变量a的值发生更改的时候,变量b和c均会随之更改;但是,如果变量b的值更改,则不会影响到c。

第二:对象父级(外层)是不可变数据类型,浅拷贝的时候不会开辟新的内存空间,同样对于内层数据无法获取。如下图所示:

变量b是元组,不可变数据类型,因此浅拷贝的时候,变量c和变量b的地址相同。同样,对于内层对象,无法拷贝,因此内层对象a的地址不变,当a的值发生变化的时候,变量b和c随之改变。

 

深拷贝

深拷贝对一个对象是所有层次的拷贝(递归),内部和外部都会被拷贝过来。

其中,外层对象为可变数据类型和不可变数据类型两种情况下,外层对象的拷贝与浅拷贝相同,不同之处在于内层对象的拷贝。下面,以下图为例:

可以看到,在深拷贝的时候,会对父级对象和内层对象均进行拷贝;因此在深拷贝得到的变量c中,内层对象a的地址也被重新分配,因此更改a的时候,变量c不会受到影响。

 

参考资料

1、https://blog.csdn.net/weixin_38819889/article/details/86476528

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值