
python 中变量赋值不创建新对象,而是建立对同一对象的引用;因此修改可变对象(如列表)会影响所有引用该对象的变量,这是语言设计的有意特性,而非 bug。
python 中变量赋值不创建新对象,而是建立对同一对象的引用;因此修改可变对象(如列表)会影响所有引用该对象的变量,这是语言设计的有意特性,而非 bug。
在 Python 中,“赋值”(=)本质上是绑定名称到对象的操作,而非复制数据。当你执行 d = c 时,并未生成 c 所指向列表的新副本,而是让变量 d 指向与 c 完全相同的内存地址中的同一个列表对象。这正是为什么后续对 d[0] 的修改(如 d[0] = 'panda')会同步反映在 c 上——因为 c 和 d 实际上是同一可变对象的两个不同“别名”。
可通过 id() 函数验证这一点:
a = 'donkey' b = 'horse' c = [a, b] d = c print(id(c) == id(d)) # 输出: True → 两者指向同一对象
⚠️ 注意:该行为仅对可变对象(如 list、dict、set)显著可见。对于不可变对象(如 str、int、tuple),即使多个变量“共享”同一对象,也无法通过赋值修改其内容(因不可变性),故不会出现意外联动。
如何真正复制列表?
若需独立副本,应显式执行浅拷贝(shallow copy):
| 方法 | 代码示例 | 说明 |
|---|---|---|
| 切片语法 | d = c[:] |
简洁常用,仅适用于序列类型 |
| 构造函数 | d = list(c) |
语义清晰,通用性强 |
copy() 方法 |
d = c.copy() |
Python 3.3+ 推荐,专为可变序列设计 |
copy 模块 |
import copy; d = copy.copy(c) |
显式且可读性高,支持更复杂场景 |
✅ 示例(修正后):
c = ['donkey', 'horse'] d = c.copy() # 或 d = c[:] d[0] = 'panda' print(c) # ['donkey', 'horse'] ← 不变 print(d) # ['panda', 'horse'] ← 仅 d 变化
? 补充提醒:以上均为浅拷贝,即仅复制最外层容器,若列表内嵌套了可变对象(如 [['a'], ['b']]),内部子对象仍被共享。需深层复制时,应使用 copy.deepcopy()。
总之,这不是 Python 的“bug”,而是其统一的对象模型体现:一切皆对象,赋值即引用绑定。理解这一机制,是写出可靠、可预测 Python 代码的关键基础。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











