Python使用[[]]*n初始化嵌套列表修改单个子列表全部同步变更问题
两种嵌套列表初始化结果差异的核心原因
两种写法的本质区别是生成的子列表是否为独立的内存对象,核心差异来自Python中可变对象的复制规则:
[[]] * 3的运行逻辑
- 首先
[[]]会创建1个空列表对象,外层列表存储的是这个空列表的内存引用 - 乘号
* 3执行的是浅复制操作,仅把这个引用复制3次,最终生成的列表a的3个元素,全部指向内存中同一个空列表对象 - 因此调用
a[0].append(3)时,修改的是所有子列表共同指向的同一个对象,所有位置的子列表都会同步变化,对应运行结果如下:
a = [[]] * 3 a[0].append(3) print(a) # 输出:[[3], [3], [3]]
for循环初始化的运行逻辑
- 每次循环执行
b.append([])时,[]都会重新创建一个全新的、独立的空列表对象,再添加到外层列表b中 - 最终
b的3个子列表分别对应3个不同的内存地址,互相完全独立 - 修改
b[0]时不会影响另外两个子列表,符合预期输出,对应运行结果如下:
b = [] for i in range(3): b.append([]) b[0].append(3) print(b) # 输出:[[3], [], []]
补充说明
如果要简洁实现独立子列表的嵌套初始化,还可以用列表推导式,效果和for循环完全一致:
c = [[] for _ in range(3)]
内容的提问来源于stack exchange,提问作者Emily Wu
相关产品推荐
相关产品推荐

