You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中用*运算符创建二维数组更新时出现意外副作用的原因

为什么Python中用[ [0]*5 ]*8创建二维数组会导致所有行同步更新?

先看你给出的代码和运行结果:

dp1 = [ [0] * 5 ] * 8
dp1[2][2] = dp1[1][1] + 1

print("DP1")
for dp in dp1: print(dp)

dp2 = [[0] * 5 for _ in range(8)]
dp2[2][2] = dp2[1][1] + 1

print("DP2")
for dp in dp2: print(dp)

输出:

DP1
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 1, 0, 0]


DP2
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]

核心原因:列表的引用复用

Python里的列表是可变对象,当你用[ [0]*5 ]*8时,本质是先创建了一个子列表[0,0,0,0,0],然后把这个子列表的引用重复了8次放到外层列表里。也就是说,dp1里的8个元素,全都是指向同一个内存地址的子列表。

你可以用id()函数验证这一点:

dp1 = [ [0]*5 ]*8
print(id(dp1[0]), id(dp1[1]), id(dp1[2]))  # 输出三个完全相同的内存地址

所以当你修改dp1[2][2]时,其实是在修改那个唯一的子列表,自然所有行都会显示出这个修改。

而方法2用的[[0]*5 for _ in range(8)],是通过列表推导式循环8次,每次循环都会新建一个[0]*5的子列表。每个子列表都是独立的对象,内存地址各不相同,修改其中一行只会影响该行本身。

总结

要创建行独立的二维数组,必须确保每一行都是新的列表实例,推荐用列表推导式的方式(方法2),或者手动循环创建每行。

内容的提问来源于stack exchange,提问作者Dracula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:15:32