
本文解释为何直接赋值 `invert = array` 会导致转置失败,并提供安全、清晰的纯 python 实现方案,强调可变对象引用与深拷贝的关键区别。
问题核心在于:invert = array 并未创建新数组,而是让 invert 和 array 指向同一块内存地址。这意味着对 invert[j][i] 的任何修改,实际上就是在修改原始 array[i][j] —— 转置过程变成“边读边写”,导致数据被提前覆盖,结果错乱。
例如,初始时 array = [[1,2,3],[4,5,6],[7,8,9]]。当 i=0, j=1 时,执行 invert[1][0] = array[0][1] 即 invert[1][0] = 2,但此时 invert 就是 array,所以 array[1][0] 立即变为 2(原为 4)。后续当 i=1, j=0 再次访问 array[1][0] 时,已不是原始值,造成逻辑崩溃。
✅ 正确做法:为 invert 分配全新的嵌套列表结构,确保与 array 完全独立:
array = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
# ✅ 正确:初始化一个同尺寸的空矩阵(深结构,非引用)
n = len(array)
invert = [[0] * n for _ in range(n)] # 推荐:简洁且安全的列表推导式
# 执行转置
for i in range(n):
for j in range(n):
invert[j][i] = array[i][j]
print(invert)
# 输出: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]⚠️ 注意事项:
- ❌ 避免 invert = array.copy() 或 invert = array[:]:它们仅做浅拷贝,内层子列表仍共享引用;
- ❌ 避免 invert = [[0]*n]*n:这会创建 n 个同一列表的引用,修改任一行都会影响所有行;
- ✅ 推荐使用 [[0] * n for _ in range(n)]:每次迭代生成全新子列表,彻底隔离;
- ? 若需原地转置(节省空间),应采用对角线交换法(仅适用于方阵),避免额外空间:
# 原地转置(无需新矩阵)
for i in range(len(array)):
for j in range(i + 1, len(array)): # 注意:j 从 i+1 开始,避免重复交换
array[i][j], array[j][i] = array[j][i], array[i][j]总结:二维列表转置失败的根本原因是混淆了“对象引用”与“对象副本”。理解 Python 中可变对象的赋值机制,是写出健壮矩阵操作代码的前提。始终确保目标容器是独立新建的,而非原始结构的别名。










