Python实现矩阵重塑时赋值导致整列同步更新的问题排查
问题原因
bug出在结果矩阵的初始化语句:
res = [[0]*c]*r
Python中对列表使用*做乘法复制时,如果被复制的元素是可变对象(比如这里的内层子列表[0]*c),不会创建多份独立的子列表,只会复制同一个子列表的内存引用。注意[0]*c本身是合法写法,因为整数是不可变对象,复制时不会出现引用共享问题;但外层用*r复制子列表时,子列表本身是可变类型,就会导致你生成的res里r个行元素,本质上全指向内存里的同一个列表。
你循环里打印的x、y索引逻辑本身没有错,但执行res[x][y] = nums.pop(0)时,不管x取什么值,修改的都是那个被所有行共享的唯一子列表,每次赋值都会覆盖上一次的值。循环结束时这个子列表里存的是最后一次弹出的元素4,所以所有行都会显示[4],就出现了你看到的整列同步更新的现象。
修正方案
把共享引用的初始化写法,替换成能生成独立子列表的列表推导式即可:
# 原错误写法 res = [[0]*c]*r res = [[0]*c for _ in range(r)]
列表推导式会循环r次,每次都生成一个全新的独立[0]*c子列表,各行之间不会共享内存引用,赋值时只会修改对应行的元素。
修正后的完整可运行代码:
def matrixReshape(mat, r, c): if len(mat)*len(mat[0]) != r*c: return mat nums = [] for row in range(len(mat)): for col in range(len(mat[0])): nums.append(mat[row][col]) # 修正初始化逻辑 res = [[0]*c for _ in range(r)] for x in range(r): for y in range(c): res[x][y] = nums.pop(0) return res mat = [[1,2],[3,4]] print(matrixReshape(mat, 4, 1))
运行后输出符合预期:
[[1], [2], [3], [4]]
补充优化提示:nums.pop(0)的时间复杂度是O(n),数据量大时效率偏低,可以换成按索引取值的方式减少性能消耗,比如用一个计数器记录当前取到nums的哪个位置,或者直接用迭代器取值。
内容的提问来源于stack exchange,提问作者idkmath28
相关产品推荐
相关产品推荐

