为何Python二维数组中修改单个子列表元素会同步改变所有子列表对应位置元素?
关于Python二维数组
[[0]*3]*3的内存引用问题 没错,你的理解完全正确!这就是Python列表乘法里很容易踩的一个“坑”,核心原因正好是你说的——所有子列表共享了同一个内存引用。
具体拆解执行逻辑:
- 先看
[0]*3:这行代码会创建一个包含三个0的列表对象,假设它在内存中的地址是A。这个列表的元素本质是指向整数0对象的引用(对于不可变的整数类型,底层细节虽有不同,但引用共享的逻辑是一致的)。 - 再看
[[0]*3]*3:这里的*3并没有生成三个新的子列表,只是把刚才那个[0]*3列表的引用复制了三次。也就是说,最终的二维数组arr其实是[指向列表A的引用, 指向列表A的引用, 指向列表A的引用],三个子列表其实是同一个对象的“别名”。
为什么修改一个子列表会同步影响所有子列表?
当你执行arr[1][0] = 4时,实际操作是:
- 通过
arr[1]拿到那个共享的列表引用, - 然后修改这个列表的第一个元素为
4。
因为arr[0]、arr[1]、arr[2]都指向同一个列表对象,所以不管通过哪个索引访问子列表,看到的都是修改后的结果——所有子列表的第一个元素都会变成4。
正确创建独立子列表的二维数组方法
如果想要每个子列表都是独立的、互不影响的对象,推荐用列表推导式:
arr = [[0]*3 for _ in range(3)]
这里的for _ in range(3)会循环三次,每次都会重新执行[0]*3来创建全新的列表对象,这样每个子列表都有自己独立的内存空间,修改其中一个不会波及其他子列表。
内容的提问来源于stack exchange,提问作者Randy
相关产品推荐
相关产品推荐

