在数据处理和算法题目中,二维方阵的原地转置是一个基础但容易出错的操作。所谓原地转置,就是在不开辟同等大小新矩阵的情况下,将方阵中第 i 行第 j 列的元素与第 j 行第 i 列的元素互换,从而让行变成列、列变成行。不少初学者在 Python 里用列表的切片或赋值来“转置”,结果因为浅拷贝导致原数据被意外修改。下面先看一个常见的错误示例。

什么是浅拷贝陷阱
在 Python 中,如果使用 b = a 或者 b = a[:],只是让新变量指向了原有的列表对象或其外层副本,内部的每一行仍然是原来的引用。此时若对 b 做转置并修改元素,a 中的数据也会跟着变。
# 错误示范:浅拷贝导致原矩阵被篡改
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = a[:] # 仅复制外层,行仍是同一引用
for i in range(3):
for j in range(i + 1, 3):
b[i][j], b[j][i] = b[j][i], b[i][j]
print('a =', a) # a 已被改变,并非原本的方阵
上面代码中,b 和 a 共享内部的三个子列表,交换 b 的元素等同于交换 a 的元素,这就落入了浅拷贝陷阱。
正确的原地转置写法
要避免该问题,应直接在原矩阵上交换对称元素,不依赖任何拷贝;或者先确保每一行都是完全独立的新列表,再做转置。
方法一:直接交换原矩阵元素
这是最标准的原地转置,只使用常量额外空间,且不会影响任何外部引用。
def transpose_in_place(matrix):
n = len(matrix)
for i in range(n):
for j in range(i + 1, n):
# 交换对称位置的元素
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
return matrix
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transpose_in_place(a)
print(a) # 输出 [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
方法二:先深拷贝行再转置
如果确实需要通过一个副本操作,应使用 list(row) 或 copy 模块生成独立的行。
import copy
def safe_transpose(matrix):
b = [list(row) for row in matrix] # 每行都是新列表
n = len(b)
for i in range(n):
for j in range(i + 1, n):
b[i][j], b[j][i] = b[j][i], b[i][j]
return b
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = safe_transpose(a)
print('a =', a) # a 保持不变
print('b =', b) # b 为转置结果
如何判断是否踩了浅拷贝
可以用 id 函数检查内部行的内存地址。若原矩阵和副本的对应行 id 相同,就说明是浅拷贝。
a = [[1, 2], [3, 4]] b = a[:] print(id(a[0]) == id(b[0])) # True 表示浅拷贝
小结
实现二维方阵原地转置时,优先采用直接交换对称元素的写法,完全规避浅拷贝。若必须另存结果,请确保每一行都是独立副本,而不是简单切片外层列表。理解引用与拷贝的区别,才能写出安全、可预期的矩阵代码。
matrix_transposein-place_algorithmshallow_copy修改时间:2026-07-28 12:33:21