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

为何两段二维数组元素更新的Python代码输出结果存在差异

两段二维列表初始化代码的输出差异原理

核心差异来源:Python 的可变对象引用规则

两种写法的根本区别是,外层大列表存储的是“共享的同一个子列表引用”还是“互相独立的多个子列表引用”,拆解执行逻辑如下:

代码1的实际执行逻辑

  • 第一步执行[0] * d时,因为0是不可变整数,这里会生成1个独立的、全新的长度为5的一维列表对象,占用独立内存空间。
  • 第二步执行[...] * d时,*运算符的作用是将当前已生成的那个一维列表的内存引用,重复、原样地复制到外层大列表的5个索引位置,不会新生成任何子列表对象。
    简单说:外层的matrix_list[0]、matrix_list[1]……matrix_list[4],存的全是同一个内存地址的指针,本质指向的是同一块列表内存。
  • 当执行matrix_list[0][3] = 1时,程序顺着matrix_list[0]存的指针,找到唯一的那块子列表内存,把第3个元素修改为1。因为所有外层索引指向的都是这块内存,遍历打印时拿到的自然全是被修改过的同一个列表,最终输出5行都带1的结果。

    踩这个坑的核心认知误区:很多开发者误以为*运算符重复可变对象时会自动创建新副本,实际上Python的*操作对可变对象只会复制引用,不会做深拷贝。

代码2的实际执行逻辑

  • 手动逐行书写的5个[0,0,0,0,0],在Python语法解析阶段,会为每一个方括号块生成拥有全新内存地址的独立一维列表对象。
  • 外层matrix_list的5个索引,分别存了5个完全不同的子列表的引用,对象之间没有任何内存关联。
  • 当执行matrix_list[0][3] = 1时,只会修改第一个引用对应的独立子列表,剩下4个子列表完全不受影响,因此输出只有第一行带1。

补充正确的二维列表初始化方式

如果要通过简写生成互不干扰的二维列表,不要直接用外层*的写法,应使用列表推导式:
matrix_list = [[0] * d for _ in range(d)]
这种写法每轮循环都会新生成一个独立的子列表,不存在共享引用的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 03:27:04