
python 中所有变量都存储对象引用,但赋值操作(如 `a = b`)只是复制引用值,而非建立引用间的动态关联;修改变量本身(如 `b = b.next`)不会影响其他已保存该引用的变量。
在链表合并等指针操作中,理解 Python 变量赋值的“快照式引用复制”机制至关重要。以 LeetCode 经典题 mergeTwoLists 为例:
curr.next = list1 # ✅ 将 list1 当前指向的 ListNode 对象的引用,赋给 curr.next list1 = list1.next # ✅ 仅改变 list1 变量自身所持有的引用,指向下一个节点
这两行代码看似连续,实则完全独立:第一行是一次性的引用拷贝——curr.next 获得了 list1 此刻所指对象的内存地址;第二行则是重新绑定 list1 这个变量名,让它指向另一个对象。这与 C/C++ 中的指针“别名”或“间接寻址”有本质区别:Python 中没有真正的“指针变量”,只有绑定到对象的名称(name)。
你提供的列表示例很好地印证了这一原理:
a = [] b = [1] a = b # a 和 b 现在绑定到同一个 list 对象 b.append(2) # 修改该对象的内容 → a 也能看到变化(因 a、b 指向同一可变对象) print(a) # [1, 2] print(id(a) == id(b)) # True —— 内存地址相同
⚠️ 关键区分点在此:
立即学习“Python免费学习笔记(深入)”;
- b.append(2) 是对对象内容的就地修改(in-place mutation) → 所有引用该对象的变量均可见;
- 而 list1 = list1.next 是对变量绑定关系的重置(rebinding) → 仅改变 list1 这个名字的指向,不影响 curr.next 已保存的旧引用。
✅ 正确类比:
把 list1 想象成一张写着“房间号 301”的便签;curr.next = list1 相当于抄下“301”贴在 curr.next 上;list1 = list1.next 则是把原便签擦掉,重写为“302”。curr.next 上的“301”不会自动变成“302”。
? 总结:
- Python 中赋值永远是引用拷贝(shallow copy of reference),不是引用绑定的“联动”;
- 要让多个变量反映同一对象的状态变化,必须通过修改对象自身属性(如 node.val = ..., lst.append()),而非重赋值变量;
- 在链表/树等数据结构操作中,curr = curr.next 或 p = p.left 都是安全的变量重绑定,不会破坏已构建的结构连接——这正是该算法能正确拼接链表的底层保障。










