Python——赋值、浅拷贝与深拷贝之间的区别

本文详细解析了Python中赋值、浅拷贝和深拷贝的区别。通过实例演示了这三种方式如何处理对象引用,以及在修改数据时的不同表现。对于理解Python的数据管理机制有重要作用。

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

在python中,赋值、浅拷贝和深拷贝,从最上层看,都可以完成将变量a的值赋予变量b。但是,三者的底层原理却是各有不同。面对不同的业务场景,三者之间并不是等价的,只有彻底搞清楚了其底层实现原理,才能做出正确的选择。

赋值

赋值就是简单的对象引用

a = [2, ['hello',3]]
b = a

在上面的代码中,a 和 b 是一样的,他们指向同一片内存,b 不过是a 的别名,是引用。使用 is方法去判断a和b,会返回 True,证明他们指向的地址相同,内容相同,还可以使用id()函数来查看两个列表的地址是否相同。

赋值操作(包括对象作为参数、返回值),在底层是不会开辟新的内存空间,它只是复制了对象的引用。也就是说除了 b 这个名字之外,没有其他的内存开销。两者本质上同一份数据。修改了 a,也就影响了b,同理,修改了b,也就影响了 a。

一句话总结:赋值运算符为整体引用的拷贝,指向的内存地址不发生变化

浅拷贝

浅拷贝(shallow copy)会创建新对象,其内容非原对象本身的引用,而是原对象内第一层对象的引用。浅拷贝有三种形式:切片操作、工厂函数、copy 模块中的 copy 函数。

# 切片操作
b = a[:] 或者 b = [x for x in a];
# 工厂函数
b = list(a);
# copy 函数
b = copy.copy(a);

浅拷贝产生的列表 b 不再是列表 a 了,使用 is 判断可以发现他们不是同一个对象,使用id查看,他们也不指向同一片内存空间。但是当我们使用 id(x) for x in a 和id(x) for x inb来查看a和b中元素的地址时,可以看到二者包含的元素的地址是相同的。

也就是说,a和b最外层的修改是各自独立的;但是a和b内部可变元素的修改是同步的。比如说

a = [1,[1,2],2]
b = a
#  此时
a[1].append(3)
print(b[1])
# [1, 2, 3]

这是因为,我们修改了嵌套的 list,修改外层元素,会修改它的引用,让它们指向别的位置,修改嵌套列表中的元素,列表的地址并未发生变化,指向的都是用一个位置。

一句话总结:浅拷贝为一层个体的引用拷贝

深拷贝

深拷贝(deep copy)只有一种形式,copy 模块中的 deepcopy()函数

深拷贝只有一种形式,copy 模块中的 deepcopy()函数。 深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因此,它的时间和空间开销要高。 同样的对列表 a,如果使用 b = copy.deepcopy(a),再修改列表b 将不会影响到列表a,即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何的关联。

一句话总结:深拷贝为递归到最底层不可变元素的引用的拷贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT_心如止水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值