使用Numpy递归原地顺时针旋转矩阵时二次迭代出现空矩阵的原因排查
问题根源分析
你遇到的IndexError本质是递归缺少终止条件,加上数据类型来回切换共同导致的:
- 递归终止逻辑缺失:当处理到边长为1或0的子矩阵时,你依然继续递归调用。比如输入是2x2矩阵时,子矩阵的索引范围
range(1,2-1)是空的,转成列表后就是[],第二次调用rotate时n = len(matrix) = 0,执行x = matrix[0]自然触发索引越界。就算是3x3矩阵,处理到中间1x1的子矩阵时,继续递归也完全没必要。 - 数据类型不一致:你一开始传入列表,函数内部转成numpy数组,递归时又转成列表传递,这种来回转换不仅容易出错,还会让空的子矩阵直接变成空列表,加剧问题。
另外,你当前的外圈旋转逻辑也有隐患:提前取出的x = matrix[0]是列表类型,后续转成numpy数组后,赋值操作可能没有正确覆盖原矩阵的元素。
修正方案
我们可以统一用numpy数组处理(操作矩阵更便捷),添加明确的递归终止条件,同时修正旋转外圈的逻辑:
import numpy as np def rotate(matrix): # 统一转成numpy数组处理(兼容列表输入) matrix = np.asarray(matrix) n = matrix.shape[0] # 递归终止条件:边长<=1时无需旋转,直接返回 if n <= 1: return matrix.tolist() # 保持和输入一致的列表格式 # 提前复制外圈四条边的数据,避免赋值时覆盖原始值 top = matrix[0, :].copy() left = matrix[1:-1, 0].copy() bottom = matrix[-1, :].copy()[::-1] # 反转后匹配旋转方向 right = matrix[1:-1, -1].copy()[::-1] # 执行外圈旋转:左→上,下→左,右→下,上→右 matrix[0, 1:] = left matrix[1:, 0] = bottom matrix[-1, :-1] = right matrix[:-1, -1] = top # 递归处理内部子矩阵,并将结果放回原矩阵 inner_matrix = matrix[1:-1, 1:-1] rotated_inner = rotate(inner_matrix) matrix[1:-1, 1:-1] = rotated_inner return matrix.tolist()
代码说明
- 递归终止条件:当矩阵边长
n <= 1时直接返回,避免处理无意义的空矩阵或单元素矩阵。 - 统一数据类型:全程用numpy数组操作,最后转成列表返回,和输入格式保持一致。
- 安全的外圈数据保存:旋转前复制四条边的数据,防止赋值时覆盖原始数据导致错误。
- 清晰的旋转逻辑:明确每条边的移动方向,确保元素正确归位。
测试你的示例输入:
# 测试3x3矩阵 print(rotate([[1,2,3],[4,5,6],[7,8,9]])) # 输出:[[7, 4, 1], [8, 5, 2], [9, 6, 3]] # 测试4x4矩阵 print(rotate([[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]])) # 输出:[[15, 13, 2, 5], [14, 3, 4, 1], [12, 6, 8, 9], [16, 7, 10, 11]]
完全符合预期结果。
内容的提问来源于stack exchange,提问作者user676464327
相关产品推荐
相关产品推荐

