You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何用*与列表推导式创建Python二维列表表现不同?

为什么修改list2的子列表会影响所有元素?

这绝对是Python新手最容易踩的经典坑之一,我来给你掰扯清楚背后的逻辑:

先拆解list2 = [[False]*2]*3的问题

你大概率以为*3是把[False, False]这个列表实实在在复制了三次,但其实不是——Python里用*复制可变对象(比如列表、字典这类)的时候,复制的不是对象本身,而是指向这个对象的引用。

换句话说,list2里的三个子列表,其实都是同一个底层列表的“别名”,它们共享同一块内存地址。就像三个人共用同一扇房门,你打开这扇门,三个人都能看到屋里的变化。所以当你执行list2[0][0] = True时,你修改的是那个唯一的底层列表,自然list2里的三个子列表都会同步显示这个变化。

你可以用id()函数直观验证,打印每个子列表的内存地址:

print(id(list2[0]), id(list2[1]), id(list2[2]))

输出的三个地址会完全相同,这就实锤了它们是同一个对象。

再看list3 = [[False]*2 for _ in range(3)]为什么正常

列表推导式的逻辑就完全不一样了:每次循环range(3),都会重新执行一次[False]*2,也就是每次都创建一个全新的列表。

所以list3里的三个子列表是三个完全独立的对象,各自拥有专属的内存地址。你修改其中一个,另外两个根本不受影响——因为它们从一开始就不是同一个东西。同样用id()验证:

print(id(list3[0]), id(list3[1]), id(list3[2]))

输出的三个地址会各不相同,这就说明它们是互相独立的。

一句话总结

  • 用*复制可变对象时,得到的是多个指向同一对象的引用,改一个就会影响所有;
  • 列表推导式会在每次迭代中生成新的对象,所以子列表之间完全独立。

内容的提问来源于stack exchange,提问作者goguma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:21:03