Python列表.reverse()与[::-1]的区别及旋转矩阵结果异常问题
LeetCode原地旋转矩阵代码差异问题
这是很多开发者都熟悉的LeetCode题目,要求实现矩阵旋转功能,不返回任何值,直接原地修改输入的矩阵。
可正常运行的reverse()版本
class Solution: def rotate(self, matrix: List[List[int]]) -> None: """ Do not return anything, modify matrix in-place instead. """ matrix.reverse() n=len(matrix) for i in range(n): for j in range(i): matrix[i][j],matrix[j][i]=matrix[j][i],matrix[i][j]
输入为[[1,2,3],[4,5,6],[7,8,9]]时,该版本可输出符合预期的结果[[7,4,1],[8,5,2],[9,6,3]]。
结果异常的[::-1]切片版本
如果仅将反转操作替换为[::-1]切片写法,代码如下:
class Solution: def rotate(self, matrix: List[List[int]]) -> None: """ Do not return anything, modify matrix in-place instead. """ matrix=matrix[::-1] n=len(matrix) for i in range(n): for j in range(i): matrix[i][j],matrix[j][i]=matrix[j][i],matrix[i][j]
相同输入下,该版本输出为[[9,6,3],[8,5,2],[7,4,1]],不符合预期。
差异原因说明
两种反转操作的元素反转逻辑没有任何区别,结果不一致的核心原因是Python的变量绑定规则和列表浅拷贝特性,和反转逻辑本身无关:
matrix.reverse()是原地方法,直接修改变量matrix指向的原外层列表对象,不会生成新列表。后续转置操作全部在原列表上执行,外部传入的矩阵会被直接修改,结果正确。matrix[::-1]会生成一个全新的外层列表,新列表仅拷贝原外层列表的引用,内部装的三个行子列表和原矩阵的子列表是完全相同的对象(浅拷贝)。当执行matrix = matrix[::-1]时,只是把函数内部的局部变量matrix重新绑定到了新生成的外层列表上,函数外部传入的原外层列表的行顺序从头到尾都没有被修改。- 后续的转置操作虽然在新外层列表上完成了正确的旋转计算,但因为子列表是原矩阵和新列表共享的,转置时的元素交换直接修改了原矩阵三个行子列表的内部值。最终外部拿到的原矩阵,外层还是初始的行顺序,行内元素却被转置操作改乱,就出现了顺序颠倒的错误结果。
如果想使用切片写法实现和
reverse()完全一致的效果,只需要把重新赋值改为切片赋值:matrix[:] = matrix[::-1],这种写法会直接替换原外层列表的内部元素,不会重新绑定局部变量,运行结果就会符合预期。
内容的提问来源于stack exchange,提问作者DeadJoker
相关产品推荐
相关产品推荐

