Python创建二维列表的引用陷阱及解决方法
Python列表乘法的陷阱:修改一个子列表为何影响全部?
先看你遇到的场景:
创建“矩阵”的代码:
m = [[0] * 2] * 3
修改其中一个元素:
m[0][1] = 1
打印结果却发现所有子列表的索引1位置都变成了1:
print(m) # 输出:[[0, 1], [0, 1], [0, 1]]
为什么会这样?
核心原因是Python的列表乘法是引用复制,不是对象复制:
- 执行
[x] * n时,不会生成n个全新的x对象,而是把同一个x的引用复制n次,放进新列表里。 - 回到你的代码:
[[0]*2] *3先生成一个子列表[0,0],然后*3是把这个子列表的引用重复3次,所以m[0]、m[1]、m[2]指向的是同一个列表对象。 - 你修改
m[0][1],本质是修改了那个被共享的列表,所有指向它的引用自然都会看到变化。
怎么解决?
要让每个子列表都是独立的对象,得逐个生成它们,不能用乘法重复引用:
方法1:列表推导式(最常用)
m = [[0]*2 for _ in range(3)]
每次循环都会新建一个[0]*2列表,三个子列表完全独立。
方法2:手动循环添加
如果不习惯推导式,也可以手动创建:
m = [] for _ in range(3): m.append([0]*2)
修改m[0][1] =1后,再打印m就会得到[[0, 1], [0, 0], [0, 0]],符合预期。
内容的提问来源于stack exchange,提问作者Mikhail Zakharov
相关产品推荐
相关产品推荐

