copy.deepcopy 变慢是因为它递归遍历所有嵌套层级,为每个可变对象新建内存副本,需反复分配内存、检查类型、维护 memo 字典防循环引用,导致时间与空间开销随嵌套深度和对象规模线性增长;实测对千级二维列表比切片慢3–5倍、内存高2–3倍。

为什么 copy.deepcopy 会变慢
因为 copy.deepcopy 是递归遍历所有嵌套层级,对每个可变对象(如子列表、字典、自定义类实例)都新建一份内存副本。遇到含上百个嵌套字典的配置结构,或几万行二维列表时,它要反复分配内存、检查类型、跳过不可变对象(如 int、str),这些开销会线性增长。实测在 Python 3.10 下,对一个含 1000 个子列表的二维结构做深拷贝,比切片慢 3–5 倍,内存占用高 2–3 倍。
哪些情况其实根本不需要 deepcopy
常见误用场景:把 copy.deepcopy 当成“保险兜底”无脑调用。实际上只要满足以下任一条件,就该换方案:
- 数据是单层列表(如
[1, 2, 3, "a"]),直接用a[:]或list(a)即可 - 你只读不写副本,或写操作仅限顶层(比如替换整个子列表
b[2] = [9, 8, 7]),浅拷贝足够 - 嵌套结构里只有固定几处需要隔离(比如只改某一层字典),可手动复制关键路径,而非全量深拷贝
- 原始数据本身不含可变嵌套(例如全是
int、str、tuple),此时copy.copy和deepcopy行为一致,但前者快得多
替代 deepcopy 的轻量方案
不是所有“要独立”都等于“必须深拷贝”。根据结构特征选更准的工具:
华为云 Python SDK 查询工具。自动发现已安装 SDK 的服务包、Client类、API 方法、入参详情、类信息(__init__ 参数、属性、类型、描述),支持关键字搜索,快速定位目标 API 使用方法。
- 二维列表初始化陷阱:别用
[[0]*3]*3,改用[[0 for _ in range(3)] for _ in range(3)]—— 每次循环生成新列表,天然隔离 - 单层含嵌套但只改外层:用
copy.copy()+ 手动重置关键子对象,例如b = copy.copy(a); b[1] = a[1].copy() - 已知结构深度为 2(如表格数据):用列表推导式重建,
b = [row[:] for row in a],比deepcopy快 2 倍以上 - 需兼容旧代码且结构稳定:给类加
__copy__方法,控制哪些字段浅拷、哪些深拷,避免全局递归
真要 deep 时怎么少花点代价
如果业务逻辑确实绕不开 copy.deepcopy(比如多线程间传递用户会话状态),可以压缩它的工作量:
立即学习“Python免费学习笔记(深入)”;
- 提前过滤掉大体积、不变的字段(如 base64 图片字符串),拷贝前 pop 出来,拷贝后再塞回去
- 用
copy.deepcopy(obj, memo={})传入空memo字典,避免它缓存中间结果带来的额外内存占用(适用于一次性小对象) - 对超大结构(>10MB),考虑用
pickle.loads(pickle.dumps(obj))替代 —— 在某些数据分布下更快,但不保证 100% 行为等价(比如带 lambda 或文件句柄的对象会失败) - 若频繁深拷贝同一模板,把模板转成不可变结构(如
tuple套frozenset),再在运行时按需构造可变副本,减少重复深拷次数
R[i][j] 却发现所有行同步变,这种问题比 deepcopy 慢更致命——它不会报错,只会悄悄污染数据。


















