Python两种3x3列表矩阵初始化方式的差异原因探究
为什么
[[0]*3]*3初始化的矩阵修改元素会异常? 核心原因:引用复用而非独立对象创建
[[0]*3]*3的本质是创建一个包含3个0的子列表,然后让外层列表的3个位置都指向这个同一个子列表,而非生成3个独立的子列表。而直接写[[0,0,0], [0,0,0], [0,0,0]]是手动创建了3个完全独立的子列表,彼此内存地址不同。
用代码验证内存指向
1. 直接定义的矩阵a
a = [[0,0,0], [0,0,0], [0,0,0]] # 打印三个子列表的内存地址 print(id(a[0])) print(id(a[1])) print(id(a[2]))
输出的三个地址完全不同,说明a[0]、a[1]、a[2]是三个独立的列表对象。修改a[0][1] = 1时,只会改变第一个子列表的元素,其余子列表不受影响。
2. 用[[0]*3]*3创建的矩阵b
b = [[0]*3]*3 # 打印三个子列表的内存地址 print(id(b[0])) print(id(b[1])) print(id(b[2]))
输出的三个地址完全相同,说明b[0]、b[1]、b[2]都是同一个子列表的引用。此时修改b[0][1] = 1,本质是修改了那个唯一的子列表,因此外层列表的三个元素指向的都是这个被修改后的子列表,最终打印b时会看到所有子列表的第2个元素都变成了1。
正确的替代初始化方式
如果想复用[0]*3的写法同时避免引用问题,可以用列表推导式生成独立子列表:
b = [[0]*3 for _ in range(3)]
每次循环都会生成一个新的[0]*3子列表,三个子列表彼此独立,修改其中一个不会影响其他。
内容的提问来源于stack exchange,提问作者Vladimir Fekete
相关产品推荐
相关产品推荐

