在字典键的帮助下填充虚拟矩阵

时间:2018-10-21 15:28:53

标签: python dictionary adjacency-matrix

我想使用字典键来获取它们各自的值,然后使用这些值来引用2D数组中的某些元素。

我确实有一个像这样创建的二维虚拟矩阵:

self.matrix = [[0] * self.length] * self.length

根据长度创建一个N x N的矩阵

我还具有名称(=键)的节点的排序列表,我想将这些名称映射到索引(=值)0..N

self.data = dict(zip(self.nodes, self.index_array))

一切正常,直到我尝试用“ 1”填充虚拟邻接矩阵为止,因为Ni连接到Nj。 “ edges”是一个元组列表:edges = [(“ u1”,“ v1”),(“ u1”,“ v2”),...,(“ ui”,“ uj”)]

for row in edges:
    self.matrix[self.data[row[0]]][self.data[row[1]]] = 1

现在,当我运行上述方法时,当节点u和节点v之间的每个连接都应该只有一个矩阵时,我得到的矩阵将充满一个矩阵。


我尝试以较小的方式对这个问题进行建模,并且在这里效果很好!我不知道发生了什么。

a = {"3": 0, "4": 1, "5": 2}
edges = [("3", "5"), ("4", "3"), ("5", "3")]
nodes = ["3", "4", "5"]
index = [0, 1, 2]

data = dict(zip(nodes, index))

matrix = [[0, 0, 0],
          [0, 0, 0],
          [0, 0, 0]]

for row in edges:
    matrix[data[row[0]]][data[row[1]]] = 1

print(a)
print(data)
print(matrix)

2 个答案:

答案 0 :(得分:0)

通过在子列表列表上使用*运算符,您可以重复对子列表的相同引用,因此对子列表所做的任何更改都将反映在所有对该子列表具有相同引用的项目上。

您可以改为使用列表理解来初始化self.matrix

self.matrix = [[0] * self.length] for _ in range(self.length)]

答案 1 :(得分:0)

这不能正确创建矩阵:

self.matrix = [[0] * self.length] * self.length

使用:

self.matrix = [[0] * self.length for _ in range(self.length)]

原因是将一个列表相乘会在列表中创建多个引用,因此每一行都是对原始代码中 same 列表的引用。

这是区别的一个例子:

>>> A = [[0] * 3] * 3
>>> A
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> A [0][0] = 1
>>> A
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

请注意以上所有三行的变化。这是由于每一行都包含 same 列表的副本:

>>> A = [[0] * 3 for _ in range(3)]
>>> A
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> A[0][0] = 1
>>> A
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]

现在为每行创建一个新的三个零的行。连续更改一个元素不会更改所有行。

请注意,[0] * 3还将引用也复制为整数零。作为一个不变的对象,这不是问题,但是,如果您有一个可变的对象,则不需要三个副本。您将使用[mutable_obj() for _ in range(3)]创建3个不同对象,因此,如果您编辑一个对象,其他对象则不会改变。