python中[[0]*3]*4出问题是因为外层乘法仅复制内层列表的引用,导致4个子列表共享同一内存地址;正确做法是用列表推导式[[0]*3 for _ in range(4)]或循环逐个创建独立副本。

Python中用*对列表做乘法时,看似是复制元素,实际是重复引用——所有子列表都指向同一内存地址,修改任一子列表会影响全部。
为什么[[0] * 3] * 4会出问题?
这种写法生成的是4个对同一个[0, 0, 0]对象的引用,不是4个独立副本。内存中只存在一个内层列表,外层数组只是多次指向它。
-
matrix = [[0] * 3] * 4→ 外层是4个相同ID的列表引用 -
matrix[0][0] = 1→ 实际改的是那个唯一内层列表的第0个元素 - 结果:
matrix变成[[1,0,0], [1,0,0], [1,0,0], [1,0,0]]
如何正确创建独立的嵌套列表?
必须确保每次生成的子列表都是新对象,不能共享引用。
- 用列表推导式:
matrix = [[0] * 3 for _ in range(4)] - 用循环逐个追加:
matrix = []; for i in range(4): matrix.append([0] * 3) - 避免在推导式中复用可变对象,例如
[[] for _ in range(3)]安全,但[[]] * 3不安全
哪些情况会触发这个陷阱?
只要涉及*作用于包含可变对象(如列表、字典、自定义类实例)的容器,就可能中招。
立即学习“Python免费学习笔记(深入)”;
-
rows = [{'name': ''}] * 5→ 5个字典引用同一对象 -
data = [User()] * 3→ 3个实例引用同一个对象(除非User重载了__mul__) - 字符串或数字等不可变类型不受影响:
['a'] * 3或[1] * 3是安全的
本质是理解Python的“对象引用”机制:*不做深拷贝,只复制引用。需要独立副本时,必须显式构造新对象。










