赋值不创建新对象,仅新增引用;浅拷贝创建新顶层对象,但嵌套可变对象仍共享。id(a)==id(b)为赋值,id(a)≠id(b)且id(a[0])==id(b[0])为浅拷贝。

引用类型赋值和浅拷贝的界限,关键在于“是否创建新对象”以及“内部可变元素是否共享”。两者表面相似,但内存行为截然不同。
赋值:不创建新对象,只加一个标签
用 = 赋值时,Python 不分配新内存,只是让新变量指向原对象的同一地址。
- 修改任意一层(包括嵌套列表、字典的键值、集合元素),另一个变量立刻同步变化
- id(a) == id(b) 恒为 True
- 本质是别名,不是复制
浅拷贝:创建新容器,但内部可变对象仍共用
浅拷贝生成一个全新的顶层对象(如新列表、新字典),但其中每个元素——尤其是可变对象——仍是原对象中对应元素的引用。
- id(a) != id(b),但 id(a[2]) == id(b[2])(若 a[2] 是列表)
- 往 b 中 追加/删除/替换顶层元素(如 b.append(x)、b[0]=99),不影响 a
- 但修改 b 中嵌套的可变对象(如 b[2].append('x')),a 对应位置也会变
常见浅拷贝写法及其适用范围
这些方式都只做一层复制:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
-
列表:
b = a[:]、b = list(a)、b = a.copy() -
字典:
b = a.copy()、b = dict(a)、b = {**a} -
通用:
import copy; b = copy.copy(a)
注意:切片 [:] 和 .copy() 对元组、字符串无效(它们本身不可变),对嵌套结构也只作用于第一层。
怎么快速判断是不是浅拷贝生效了?
两个检查点:
- 运行
id(a) == id(b)→ 若为 False,说明至少顶层已分离(排除了赋值) - 再运行
id(a[0]) == id(b[0])(假设 a[0] 是个列表)→ 若为 True,说明嵌套对象未复制,正是浅拷贝特征
只要第二步为 True,就还没脱离浅拷贝范畴;只有深拷贝才能让所有层级的 id 都不同。










