深入理解 Python 中的浅拷贝与深拷贝

本文详细解释了Python中浅拷贝和深拷贝的概念,介绍了它们在数据结构复制中的行为差异,包括定义、使用方法、适用场景和内存效率,并通过示例展示了两者在实际操作中的表现。
摘要由CSDN通过智能技术生成

在 Python 中,数据复制是常见需求。复制机制分为“浅拷贝(shallow copy)”和“深拷贝(deep copy)”,这两种方式在处理复杂数据结构时的行为差异极大。下面详细解析这两种拷贝方法,包括它们的定义、如何使用、适用场景以及它们在内存操作上的不同表现。


1. 基本概念

1.1 前置知识

在 Python 中,所有数据都是以对象的形式表示的,这包括简单的数值、字符串,以及复杂的列表、字典等。

对象可以分为“可变对象”和“不可变对象”。

  • 不可变对象(如整数、字符串和元组)不允许对象本身的内容被改变
  • 可变对象(如列表、字典)则允许对象内容的修改。

1.2 浅拷贝(Shallow Copy)

浅拷贝仅仅复制数据结构的第一层对象本身,如果对象包含了其他对象的引用,则这些引用的地址不变。也就是说,浅拷贝创建了一个新对象,但是这个新对象中填充的是对原始对象内容的引用(即地址)。
在这里插入图片描述

1.3 深拷贝(Deep Copy)

深拷贝对原始数据的完全拷贝,包括数据结构中的所有层级。如果原始对象中含有对其他对象的引用,深拷贝不仅复制结构本身,还会递归地复制所有引用的具体内容,因此新对象与原始对象无任何关联。
在这里插入图片描述

2. 如何实现浅拷贝和深拷贝

Python 的 copy 模块提供了实现浅拷贝和深拷贝的方法。

示例代码

以下代码演示了浅拷贝与深拷贝的基本用法:

import copy

# 创建一个包含其他对象的复杂对象
original_list = [1, 2, [3, 4], {'a': 5}]

# 浅拷贝: 复制顶层对象,内部容器对象如列表和字典保持引用不变
shallow_copied_list = copy.copy(original_list)

# 深拷贝: 完全复制所有层级的对象,无引用关系保留
deep_copied_list = copy.deepcopy(original_list)

# 修改原始数据中的列表和字典
original_list[2].append(5)  # 这会影响浅拷贝中的相应列表
original_list[3]['a'] = 6   # 这也会影响浅拷贝中的相应字典

# 输出原始数据和两种拷贝的结果
print("Original:", original_list)       # 显示原始对象的当前状态
print("Shallow Copy:", shallow_copied_list)  # 显示浅拷贝对象的当前状态
print("Deep Copy:", deep_copied_list)        # 显示深拷贝对象的当前状态

运行结果

运行上述代码会得到以下输出:

Original: [1, 2, [3, 4, 5], {'a': 6}]
Shallow Copy: [1, 2, [3, 4, 5], {'a': 6}]
Deep Copy: [1, 2, [3, 4], {'a': 5}]
  • 浅拷贝对象的子列表和字典与原始对象一致,因为它们是引用。
  • 深拷贝对象的子列表和字典独立于原始对象,对原始对象的修改不影响深拷贝对象。

3. 深入分析

内存效率

浅拷贝由于只复制一层对象,因此在执行速度和所占内存上比深拷贝更为高效。对于大规模数据结构,频繁使用深拷贝可能导致明显的性能下降。

使用场景

  • 浅拷贝适用于对象结构简单或只需复制顶层结构的场景。比如当需要复制的对象包含大量不可变数据或共享数据时。
  • 深拷贝则适用于需要完全独立副本的复杂数据结构,如多层嵌套的列表或字典。

注意事项

在使用深拷贝时,需要注意递归引用的问题,即对象自身直接或间接地引用了自己。这种情况下,深拷贝会尝试无限复制,最终导致栈溢出错误。


参考:copy in Python (Deep Copy and Shallow Copy)
推荐: python 错误记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Peter-Lu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值