Python 3.6.2二维列表疑似延迟初始化问题:修改元素全列表同步变化求解释
为什么修改
a[0][0]会让所有子列表的第一个元素都变成1? 嘿,这个问题其实是Python初学者很容易踩的一个典型坑,我来给你把底层逻辑掰扯明白~
首先拆解你写的代码:
[0]*3确实能创建一个包含三个0的列表[0,0,0],这一步没问题。- 但
[[0]*3]*3的操作并不是创建三个独立的子列表,而是把刚才那个[0,0,0]列表的引用复制了三次。也就是说,变量a里的三个元素,其实指向的是内存中同一个列表对象!
你可以用id()函数验证这一点,比如运行下面的代码:
a = [[0]*3]*3 print(id(a[0])) print(id(a[1])) print(id(a[2]))
你会发现这三个输出的内存地址完全相同,实锤了它们是同一个对象。
那为什么修改a[0][0] = 1会让所有子列表的第一个元素都变呢?因为你根本不是在修改第一个子列表的元素,而是在修改那个唯一的子列表里的元素——三个子列表只是它的“别名”而已,所有别名自然会同步看到这个变化。
正确的创建方式
要创建三个独立的子列表,你应该用列表推导式:
a = [[0]*3 for _ in range(3)]
这个写法会在每次循环中重新创建一个[0]*3列表,这样a里的三个子列表就是完全独立的对象了。此时再修改a[0][0] = 1,输出就会是你预期的[[1, 0, 0], [0, 0, 0], [0, 0, 0]]。
内容的提问来源于stack exchange,提问作者Rohith Yeravothula
相关产品推荐
相关产品推荐

