[英]Creating an undirected graph given a List
I have a List: 我有一个清单:
entry=['A','B','C','null','B','A','D','null','E','F']
Letters (vertexes) adjacent to each other form an edge. 彼此相邻的字母(顶点)形成边缘。 'null' is a separator. 'null'是一个分隔符。
Each edge has weight 1. Edge (A,B) has weight two, since it occurs twice. 每个边缘具有重量1.边缘(A,B)具有重量2,因为它发生两次。
To visualize, above list will be this graph: 为了可视化,上面的列表将是这个图:
I want to create a dictionary, similar to adjacency list. 我想创建一个类似于邻接列表的字典。
dict= {
'A':{'B':2,'D',1},
'B':{'A':2,'C':1},
'C':{'B':1},
'D':{'A':1},
'E':{'F':1},
'F':{'E':1}
}
Where first key is a vertex, second keys are neighboring vertexes with its weight values. 在第一个键是顶点的情况下,第二个键是具有其权重值的相邻顶点。
How to come up with above graph. 如何拿出上面的图表。 If there are any other better way of representation of above graph, I'd appreciate any help. 如果有任何其他更好的方式来表示上图,我会感激任何帮助。
One solution is to reduce
your entry
list to the graph dictionary as reduce (without an accumulator) looks at 2 adjacent elements at a time: 一种解决方案是将entry
列表reduce
到图表字典,因为reduce(没有累加器)一次查看2个相邻元素:
from functools import reduce
graph = {}
def add_edge(u, v):
if u != 'null' and v != 'null':
if u in graph:
graph[u][v] = graph[u].get(v, 0) + 1
else:
graph[u] = {v: 1}
if v in graph:
graph[v][u] = graph[v].get(u, 0) + 1
else:
graph[v] = {u: 1}
return v
entry = ['A','B','C','null','B','A','D','null','E','F']
reduce(add_edge, entry)
print(graph)
# {'B': {'A': 2, 'C': 1}, 'E': {'F': 1}, 'F': {'E': 1}, 'C': {'B': 1}, 'A': {'B': 2, 'D': 1}, 'D': {'A': 1}}
Edit : 编辑 :
A "purer" way to reduce would be to zip adjacent elements together and then reduce with an initializer: 一种“更纯粹”的减少方法是将相邻元素压缩在一起然后用初始化器减少:
def add_edge(graph, edges):
u, v = edges
if u != 'null' and v != 'null':
# ... same thing as before
return graph
entry = ['A','B','C','null','B','A','D','null','E','F']
graph = reduce(add_edge, zip(entry[:-1], entry[1:]), {})
Piggy backing on @slider answer, you can also use map
(which is builtin, no imports needed) for this: @slider回答小猪支持,你也可以使用map
(内置,不需要导入):
graph = {}
def add_edge(l):
u, v = l[0], l[1]
if u != 'null' and v != 'null':
if u in graph:
graph[u][v] = graph[u].get(v, 0) + 1
else:
graph[u] = {v: 1}
if v in graph:
graph[v][u] = graph[v].get(u, 0) + 1
else:
graph[v] = {u: 1}
return v
list(map(add_edge, [entry[i:i+2] for i in range(len(entry) - 1)]))
>>> graph
{'A': {'B': 2, 'D': 1},
'B': {'A': 2, 'C': 1},
'C': {'B': 1},
'D': {'A': 1},
'E': {'F': 1},
'F': {'E': 1}}
The reason for using list(map(func..))
is because for python 3, map
returns a generator instead of executing, hence have to use list to force it to execute. 使用list(map(func..))
的原因是因为对于python 3, map
返回生成器而不是执行,因此必须使用list来强制它执行。 The output of that line is not of interest to us. 该行的输出对我们不感兴趣。 If you're using python 2, then you can just use map(func..)
如果你正在使用python 2,那么你可以使用map(func..)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.