为何Python中创建二维数组的方式不同会导致行为差异?
为什么修改二维数组的一个元素会影响整列?
这问题我刚入门Python的时候也踩过一模一样的坑!核心原因在于列表乘法创建的是对象引用的重复,而不是独立的新对象。
咱们拆解来看你的两个代码:
1. 问题出在counter= 3*[4*[0]]
当你执行4*[0]时,Python会创建一个列表对象[0,0,0,0]。然后3*[...]做的事情是:把这个同一个列表对象的引用重复3次,放进外层列表里。也就是说,counter[0]、counter[1]、counter[2]其实指向的是内存里的同一个子列表!
所以当你修改counter[0][3] =7时,本质是修改了那个唯一的子列表的元素,自然所有指向它的位置都会显示变化——就像你有三把钥匙开同一扇门,打开门改了屋里的东西,用另外两把钥匙开门看到的也是修改后的样子。
你可以用id()函数验证这一点:
counter = 3*[4*[0]] print(id(counter[0]), id(counter[1]), id(counter[2])) # 输出的三个ID完全相同,说明是同一个对象
2. 手动定义的T为什么正常?
而T = [[0, 0, 0, 0], [0, 0,0,0], [0, 0, 0, 0]]这种写法,每一个[0,0,0,0]都是Python单独创建的新列表对象,它们在内存里是完全独立的。修改其中一个子列表的元素,只会影响它自己,其他子列表不受影响。
同样用id()验证:
T = [[0,0,0,0], [0,0,0,0], [0,0,0,0]] print(id(T[0]), id(T[1]), id(T[2])) # 输出的三个ID各不相同,说明是三个独立对象
正确创建二维数组的方法
如果想要用简洁的方式创建独立子列表的二维数组,推荐用列表推导式:
counter = [[0]*4 for _ in range(3)] counter[0][3] =7 print(counter) # 输出:[[0, 0, 0, 7], [0, 0, 0, 0], [0, 0, 0, 0]]
这里的for _ in range(3)会循环3次,每次都创建一个新的[0]*4列表,所以每个子列表都是独立的,不会出现“牵一发而动全身”的问题。
内容的提问来源于stack exchange,提问作者David Raji
相关产品推荐
相关产品推荐

