20 分钟
Python 进阶

深浅拷贝陷阱

为什么修改副本会影响原对象?引用与拷贝的本质

  • 理解 Python 中赋值是引用而非拷贝
  • 区分浅拷贝和深拷贝
  • 掌握 copy.copy 和 copy.deepcopy
  • 知道哪些操作会创建副本

深浅拷贝陷阱

改了 b,a 也跟着变了——这是 Python 里新手最容易懵的问题。

赋值不是拷贝

示例代码(可运行)
ℹ️核心概念:引用

Python里变量存的不是值本身,是对象的引用(内存地址)。a = [1,2,3] 让a指向列表对象;b = a 让b也指向同一个对象。就像一个人有两个名字,叫哪个都是同一个人。

浅拷贝:只拷一层

示例代码(可运行)

深拷贝:完全独立

示例代码(可运行)

什么时候用哪种?

示例代码(可运行)
⚠️[[0]*n]*n 经典陷阱

创建二维列表别用 [[0]*cols]*rows,这会让所有行引用同一个列表。正确写法:[[0]*cols for _ in range(rows)],列表推导每次迭代创建新列表。

CPython源码

Python 拷贝机制底层

拷贝的本质是创建新对象,但内容怎么复制,得看是什么类型。

示例代码(可运行)
找 Bugoriginal[:] 是浅拷贝,内层列表共享。修改 copy_list[0][1] 影响了 original。需要 deepcopy。
original = [["张三", 90], ["李四", 85]] copy_list = original[:] copy_list[0][1] = 95 print(original[0][1])

资深工程师加餐

底层原理 · 大厂视角 · 工程经验,点卡片展开

list 底层是一段连续的指针数组,容量不够时整体扩容(CPython 约按 1.125 倍)。因此按下标取元素是 O(1),末尾 append 均摊 O(1),但在头部 insert(0,…) 或 pop(0) 要搬动全部元素、是 O(n)。dict/set 基于哈希表,平均查找 O(1) 但更耗内存。选对数据结构,往往比抠语法更影响性能。

挑战任务

安全的列表复制

简单+50 XP

创建一个二维 3x3 棋盘,修改副本不影响原棋盘。

安全的列表复制
2 个测试用例

课后作业

独立成绩单

中等+20 XP

有一个嵌套的成绩字典,创建完全独立的副本并修改,验证原数据不变。

独立成绩单
1 个测试用例