应对复杂嵌套对象拷贝的核心是理解“改哪一层会影响原对象”并按需选择复制粒度:赋值不等于拷贝;只读无需拷贝;浅拷贝适用于不可变子对象或仅操作顶层;深拷贝用于含可变嵌套结构;性能敏感时可用列表推导、手动逐层copy或json序列化替代。

应对复杂嵌套对象拷贝的核心,是理解“改哪一层会影响原对象”,并按需选择复制粒度。
先判断是否真需要拷贝
很多问题其实源于误用赋值:a = b 并不是拷贝,只是多了一个名字指向同一块内存。如果后续只读不改,根本不需要 copy;如果只是临时隔离某次函数调用的输入,可在函数开头 deepcopy 一次,避免污染上游数据。
浅拷贝够用的场景
当嵌套结构里所有子对象都是不可变类型(如字符串、数字、元组),或你明确只操作顶层元素时,浅拷贝安全又高效:
- 用 list.copy() 或 [:] 处理一维列表
- 用 dict.copy() 复制键值对,且值全是字符串或数字
- 修改副本的顶层项(如
b[0] = 100或d['name'] = 'Alice')不会波及原对象
必须用深拷贝的情况
只要嵌套中存在可变对象(列表、字典、集合、自定义类实例),且你可能修改其内部内容,就必须用 copy.deepcopy():
- 二维及以上列表:
[[1,2], [3,4]] - 含列表的字典:
{'data': [1,2,3], 'meta': {'version': 2}} - Pydantic 模型或 Beanie Document 的嵌套字段(如
user.profile.address)
它会递归复制每一层,确保 new[0][1] 和 original[0][1] 完全无关。
性能敏感时的替代方案
deepcopy 开销大,若结构固定且层级已知,可用更轻量的方式:
- 二维列表:用
[row[:] for row in original]或[row.copy() for row in original] - 三层以内字典+列表混合:手动逐层 copy,比如先
outer = original.copy(),再对每个可变值单独copy.copy(v) - 仅限 JSON 兼容数据:
json.loads(json.dumps(obj))(不支持函数、datetime、自定义类)

















