为何Python修改矩阵单个元素时会批量改整列?仅全同行时出现
为什么修改Python矩阵元素时整列被替换?
现象描述
当修改矩阵中的单个元素时,有时会出现整列元素都被替换的情况,但这种情况仅发生在矩阵所有行完全指向同一个列表对象时。比如以下示例中,test_matrix修改单个元素后整列变化,而sec_matrix修改行为符合预期:
def print_matrix(matrix: list[list], dlm: str) -> None: for row in matrix: for col in row: print(col, end=dlm) print() one_row = list(range(4)) test_matrix = [] for i in range(5): test_matrix.append(one_row) test_matrix[0][0] = 5 sec_matrix = [ [0,1,2,3], [0,1,2,3], [0,1,2,3], [0,1,2,4] ] sec_matrix[0][0] = 5 print_matrix(test_matrix, ' ') print() print_matrix(sec_matrix, ' ')
运行结果中,test_matrix的所有行第一个元素都变成了5,而sec_matrix只有第一行第一个元素被修改。
原因分析
这两种矩阵的处理方式不同,核心在于列表对象的引用关系:
test_matrix的每一行都是通过append(one_row)添加的,这里添加的不是列表的副本,而是one_row这个列表对象的内存引用。也就是说,矩阵里的5行其实指向同一个列表,修改test_matrix[0][0]本质是修改那个唯一的列表,所有行自然会同步变化。sec_matrix的每一行都是单独定义的列表(哪怕内容看起来完全一致),它们是独立的内存对象,彼此没有引用关联,修改其中一行的元素只会影响该行本身。
疑问解答
这不是Python的Bug,是完全符合预期的行为:
- Python不会因为两个列表内容相同就将它们视为同一个对象,判断依据是内存中的引用地址,而非内容。
- 这种情况也不是Python为了性能自动复用列表,而是你在代码中主动复用了同一个列表对象导致的。
解决方法
要避免这种问题,创建矩阵时需要确保每一行都是独立的列表对象,常见的做法有两种:
- 每次循环创建新列表:
test_matrix = [] for i in range(5): test_matrix.append(list(range(4))) # 每次生成新列表 - 对原列表进行复制:
one_row = list(range(4)) test_matrix = [] for i in range(5): test_matrix.append(one_row.copy()) # 复制原列表生成新对象
内容的提问来源于stack exchange,提问作者rmm2908
相关产品推荐
相关产品推荐

