在字典键的帮助下填充虚拟矩阵
Fill a dummy matrix with help of dictionary keys
我想使用字典键获取它们各自的值,然后使用这些值引用我的二维数组中的某些元素。
我确实有一个二维虚拟矩阵,我是这样创建的:
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
现在,当我 运行 上面的方法时,我得到一个全是 1 的矩阵,而节点 u 和节点 v 之间的每个连接应该只有 1 个
我尝试以更小的方式对这个问题进行建模,在这里效果很好!不知道怎么回事
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)
通过在子列表列表上使用 *
运算符,您将重复对子列表的相同引用,因此对子列表所做的任何更改都将反映在对子列表具有相同引用的所有其他项目上子列表。
您可以使用列表理解来初始化 self.matrix
:
self.matrix = [[0] * self.length] for _ in range(self.length)]
这没有正确创建矩阵:
self.matrix = [[0] * self.length] * self.length
使用:
self.matrix = [[0] * self.length for _ in range(self.length)]
原因是列表相乘会创建列表中引用的倍数,因此每一行都是对原始代码中相同列表的引用。
这是一个差异示例:
>>> 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 个 不同的 对象,因此如果您编辑一个对象,其他对象不会改变。
我想使用字典键获取它们各自的值,然后使用这些值引用我的二维数组中的某些元素。
我确实有一个二维虚拟矩阵,我是这样创建的:
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
现在,当我 运行 上面的方法时,我得到一个全是 1 的矩阵,而节点 u 和节点 v 之间的每个连接应该只有 1 个
我尝试以更小的方式对这个问题进行建模,在这里效果很好!不知道怎么回事
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)
通过在子列表列表上使用 *
运算符,您将重复对子列表的相同引用,因此对子列表所做的任何更改都将反映在对子列表具有相同引用的所有其他项目上子列表。
您可以使用列表理解来初始化 self.matrix
:
self.matrix = [[0] * self.length] for _ in range(self.length)]
这没有正确创建矩阵:
self.matrix = [[0] * self.length] * self.length
使用:
self.matrix = [[0] * self.length for _ in range(self.length)]
原因是列表相乘会创建列表中引用的倍数,因此每一行都是对原始代码中相同列表的引用。
这是一个差异示例:
>>> 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 个 不同的 对象,因此如果您编辑一个对象,其他对象不会改变。