为何Python构建邻接矩阵时始终写入同一行而非遍历行?
邻接字典转邻接矩阵时所有行同步修改的问题
我尝试从邻接字典创建邻接矩阵,先初始化全零空矩阵,再遍历邻接字典为矩阵赋值权重。但代码始终把值写入"同一行",最终所有行内容完全一致。使用Python 3.7,赋值方式为matrix[][]。
代码示例
digraph = make_digraph() # 创建包含adj_dict的类实例 adj_matrix = [[0] * len(digraph.adj_dict)] * len(digraph.adj_dict) # 初始化空矩阵 print(adj_matrix) for source, destinations in digraph.adj_dict.items(): for destination in destinations: print(int(source[1:]), int(destination[1:]), digraph.adj_dict[source][destination]) adj_matrix[int(source[1:])][int(destination[1:])] = digraph.adj_dict[source][destination] print(adj_matrix)
实际输出
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 0 1 4 1 2 1 1 7 2 1 8 2 2 11 3 3 4 1 3 12 2 4 5 1 4 8 3 4 14 2 5 6 2 5 9 2 6 0 1 6 10 2 7 9 2 8 9 2 8 11 1 10 0 1 10 7 2 10 9 3 11 1 4 11 12 4 12 2 1 12 8 3 12 13 2 13 4 2 14 9 2 [[1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2], [1, 4, 1, 0, 2, 1, 2, 2, 3, 2, 2, 1, 4, 2, 2]]
比如第二次循环的1 2 1,我预期赋值adj_matrix[1][2] = 1,但实际所有行的第2列都变成了1,所有行内容完全同步。
问题原因与解决方法
问题根源
初始化矩阵的[[0] * len(digraph.adj_dict)] * len(digraph.adj_dict)写法存在陷阱:外层的*只是将同一个列表对象重复引用了多次,矩阵里的每一行都是同一个列表的引用。修改任何一行时,所有行都会同步变化。
解决方法
改用列表推导式初始化矩阵,确保每一行都是独立的新列表:
n = len(digraph.adj_dict) adj_matrix = [[0] * n for _ in range(n)]
修正后的完整代码
digraph = make_digraph() # 创建包含adj_dict的类实例 n = len(digraph.adj_dict) adj_matrix = [[0] * n for _ in range(n)] # 初始化独立行的空矩阵 print(adj_matrix) for source, destinations in digraph.adj_dict.items(): for destination in destinations: row = int(source[1:]) col = int(destination[1:]) weight = digraph.adj_dict[source][destination] print(row, col, weight) adj_matrix[row][col] = weight print(adj_matrix)
修改后,每一行都是独立的列表,赋值只会影响指定的行和列,不会出现所有行同步修改的问题。
内容的提问来源于Stack Exchange,提问作者M. Rom
相关产品推荐
相关产品推荐

