You need to enable JavaScript to run this app. Python列表推导式与乘法初始化二维列表后修改结果差异原因
优惠活动
大模型
产品
解决方案
定价
更多

Python列表推导式与乘法初始化二维列表后修改结果差异原因

二维列表两种初始化方式的行为差异根因

核心本质

两种初始化方式输出的初始列表外观完全一致,但底层对独立对象的创建逻辑完全不同,列表乘法操作的核心特性是只复制对象引用,不会生成全新的独立对象,这是最终修改结果出现偏差的根本原因。

列表推导式初始化的执行逻辑

对应实现代码:

C1 = [[0 for x in range(r+1)] for x in range(n+1)]
  • 外层循环每迭代一次,都会重新执行一次内层的列表推导逻辑,当场生成一个拥有独立内存地址的全新子列表
  • 所有生成的子列表互相独立,不存在引用关联,因此单独修改任意子列表的元素,只会影响该子列表本身,不会波及其他子列表,完全符合赋值操作的预期效果。

列表乘法初始化的执行逻辑

对应实现代码:

C2 = [[0] * (r+1)] * (n+1)

分步拆解实际执行过程:

  1. 先执行内层的[0] * (r+1):由于0是不可变的整型值,这一步会生成一个存储了7个0的独立子列表对象,记为对象A
  2. 再执行外层的[对象A] * (n+1):Python中列表乘法的固定规则是,将列表内已有元素的引用重复N次拼接为新列表,整个过程不会创建新的子列表,只是把指向对象A的引用复制6份,依次塞入外层列表
  • 最终C2的所有元素,本质上都是指向同一个子列表对象A的引用,从初始化开始就不存在多个独立的子列表
  • 当执行C2[4][3] = 4的赋值操作时,实际修改的是那个唯一的公共子列表对象A的第3位元素,因此所有引用对象A的外层位置,都会同步显示修改后的内容,最终出现“修改单个元素,所有子列表同步变化”的现象。

直观验证方法

可以通过Python内置的id()函数查看对象的内存地址,直接验证底层差异:

  • 对C1执行id(C1[0]) == id(C1[4]),返回结果为False,说明两个位置是相互独立的不同对象
  • 对C2执行id(C2[0]) == id(C2[4]),返回结果为True,说明两个位置指向完全相同的同一个对象

内容的提问来源于stack exchange,提问作者Rahul M Dinesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 09:15:08