Python用嵌套列表创建矩阵的基础方法

Hazel
Hazel
发布时间:2026-10-24| 5人浏览过
原创

在 Python 原生环境中,标准库并没有专门提供像 C 语言二维数组那样直接的矩阵数据类型。开发者通常使用“嵌套列表”(Nested Lists)来模拟二维矩阵:将外层列表视为行的集合,其中的每个内层列表视为一行数据,内层列表的每个元素则对应各个列单元格。本文将详细讲解使用嵌套列表构建矩阵的三种基础途径、读写坐标与尺寸计算方法,并重点剖析初学者极易踩坑的乘法浅拷贝陷阱。

一、核心概念:嵌套列表与二维矩阵的映射

要掌握矩阵的创建,首先需要建立直观的逻辑映射。所谓嵌套列表,即列表中的元素本身也是列表。在表示二维矩阵时,普遍采用“行优先”(Row-Major)的对应关系:

  • 外层列表:长度代表矩阵的总行数(rows)。外层列表的第 i 个元素就是矩阵的第 i 行。
  • 内层列表:长度代表矩阵的总列数(cols)。每个内层列表保存该行中从左到右的所有列值。
  • 坐标索引:通过两次连续的下标索引 matrix[row_index][col_index] 访问特定位置。Python 索引统一从 0 开始。
Python用嵌套列表创建矩阵的基础方法
图 1:嵌套列表与二维矩阵网格、坐标索引的对应关系示意

二、方法一:直接字面量声明

当矩阵的规模较小、初始元素已知且固定时,最清晰直观的做法就是直接使用字面量定义。将各个内层列表用中括号包裹,并以外层中括号聚合。

# 示例:直接定义一个 3 行 3 列的固定矩阵
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 访问元素
print("第 0 行第 1 列的值为:", matrix[0][1])  # 示例输出: 2
print("第 2 行第 2 列的值为:", matrix[2][2])  # 示例输出: 9

# 修改元素
matrix[1][1] = 99
print("修改后的第 1 行:", matrix[1])        # 示例输出: [4, 99, 6]

这种方法编写简单、排版整齐,常用于单元测试、算法题初始化常量测试用例,或者坐标转换矩阵的硬编码定义。但当矩阵尺寸是由程序运行时的动态参数(如行数 m、列数 n)决定时,字面量书写就无法满足需求,必须采用动态生成方式。

三、方法二:列表推导式动态构建(标准推荐方法)

在实际编程中,最普遍的需求是创建一个指定行数 rows 和列数 cols,且所有位置都填充默认初值(如 0)的矩阵。在 Python 中,列表推导式(List Comprehension)是完成此任务兼具高效、优雅且无副作用的推荐途径。

1. 常用推导式语法

rows = 3
cols = 4

# 方式 A:内层列表使用乘法,外层使用推导式迭代(最常用写法)
matrix = [[0] * cols for _ in range(rows)]

# 方式 B:双层嵌套列表推导式(完全显式展开)
matrix_explicit = [[0 for _ in range(cols)] for _ in range(rows)]

# 验证生成结果
print("生成的矩阵:")
for row in matrix:
    print(row)

# 示例输出:
# [0, 0, 0, 0]
# [0, 0, 0, 0]
# [0, 0, 0, 0]

这里的关键在于外层的 for _ in range(rows)。在每一次循环迭代中,Python 都会重新计算并生成一个全新的、拥有独立内存地址的内层列表,然后将这 rows 个互不相干的列表收集装入外层列表中。

Python用嵌套列表创建矩阵的基础方法
图 2:列表推导式按部就班创建独立行对象的执行流程

四、关键陷阱辨析:为什么绝对不能用 [[0] * n] * m?

很多 Python 初学者在了解 [0] * 3 会生成 [0, 0, 0] 之后,会非常自然地写出以下代码:

# ❌ 错误示范:极其隐蔽的浅拷贝陷阱
rows = 3
cols = 3
bad_matrix = [[0] * cols] * rows

print(bad_matrix)
# 打印结果看似完全正常: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

初看控制台输出,确实是 3 行 3 列全 0 矩阵。然而,当你尝试修改任意一个具体单元格时,意外就会发生:

# 尝试仅修改第 0 行第 0 列为 1
bad_matrix[0][0] = 1

print("修改后的 bad_matrix:")
for r in bad_matrix:
    print(r)

# 实际控制台输出:
# [1, 0, 0]
# [1, 0, 0]
# [1, 0, 0]  <-- 每一行的第 0 列竟然全都被修改了!

底层原因解析:Python 中的列表是可变对象(Mutable Object)。在表达式 [[0] * 3] * 3 中,内层的 [0] * 3 确实成功创建了一个列表对象;但随后的外层 * 3 并不是创建 3 个新的列表,而是将这同一个列表对象的内存引用(引用地址)连续复制了 3 次。

因此,bad_matrix[0]、bad_matrix[1] 和 bad_matrix[2] 实际在内存中指向完全相同的同一个列表。修改其中任何一行的元素,其他行都会同步发生变化,导致整个矩阵逻辑崩溃。

Python用嵌套列表创建矩阵的基础方法
图 3:乘法浅拷贝共享同一引用与推导式独立引用的内存结构对比

五、方法三:循环遍历与动态添加(从空列表构建)

当矩阵的初值并非固定的常量,而是依赖复杂的数学公式计算得出,或者需要从外部文件、用户标准输入流逐行流式解析时,常规的 for 循环搭配 append() 是最具扩展性的写法。

rows = 3
cols = 4
matrix = []

for r in range(rows):
    # 步骤 1:为当前行创建一个全新的空列表
    current_row = []
    for c in range(cols):
        # 步骤 2:根据行号和列号计算数值并追加
        value = r * cols + c + 1
        current_row.append(value)
    # 步骤 3:将构建完毕的行加入外部矩阵
    matrix.append(current_row)

print("动态递增填充的矩阵:")
for row in matrix:
    print(row)

# 示例输出:
# [1, 2, 3, 4]
# [5, 6, 7, 8]
# [9, 10, 11, 12]

该方法的逻辑与列表推导式完全一致,好处在于代码步步清晰,利于在内层循环中插入条件分支、数据清洗或异常校验逻辑。

六、矩阵的基本操作与边界注意事项

掌握了创建方法后,在后续使用嵌套列表矩阵时,还应遵守以下几条核心操作规范:

1. 动态获取矩阵的行列尺寸

在编写矩阵算法(如求转置、矩阵乘法、遍历搜索)时,通常需要先获取矩阵的规格:

# 获取行数
num_rows = len(matrix)

# 获取列数(前提是矩阵非空,且每一行长度规整)
num_cols = len(matrix[0]) if num_rows > 0 else 0

print(f"矩阵规格为:{num_rows} 行 × {num_cols} 列")

2. 防止越界与行先列后原则

始终牢记第一维索引对应行(row),第二维索引对应列(col)。初学者容易习惯性将其写成笛卡尔坐标系的 matrix[x][y],从而颠倒了行列顺序,导致产生 IndexError: list index out of range 异常。

3. 不规则矩阵(Jagged List)隐患

Python 原生列表不强制要求内层列表长度一致。例如 [[1, 2], [3, 4, 5]] 在语法上完全合法,但它并不是标准数学意义上的矩形矩阵。若后续代码假设所有行具有相同列数直接调用 len(matrix[0]),在处理不规则数据时便可能引发越界错误。在处理外部输入时,建议校验 all(len(row) == len(matrix[0]) for row in matrix)。

七、总结与方法选择参考

下表归纳了创建 Python 嵌套列表矩阵的三种常见方法及其各自的优缺点与适用场景:

创建方式 核心语法示例 适用场景 注意事项
字面量直接声明 [[1, 2], [3, 4]] 小型固定测试数据、单位矩阵或预定义常量 代码直观,但无法按运行时参数动态定义尺寸
列表推导式(推荐) [[0] * cols for _ in range(rows)] 动态指定规格,且需要赋予统一初值(如 0 或 None) 务必保持外层为推导式循环,绝不可写成 [[0]*n]*m
双重循环动态追加 for r in ...: row.append(...) 元素值依赖复杂数学计算、条件判断或文件输入解析 执行过程直观易懂,可在每步加入过滤或校验逻辑
Python用嵌套列表创建矩阵的基础方法
图 4:Python 嵌套列表矩阵核心方法、规则及避坑速查卡片
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。