Python 从NetworkX MultiDiGraph中删除自循环会导致运行时错误
我有一个NetworkX有向图,它包含自循环。根据,这是多有向图的一个有效性质 多有向图包含有向边。允许自循环 但是,当我尝试使用Python 从NetworkX MultiDiGraph中删除自循环会导致运行时错误,python,networkx,Python,Networkx,我有一个NetworkX有向图,它包含自循环。根据,这是多有向图的一个有效性质 多有向图包含有向边。允许自循环 但是,当我尝试使用MG.remove_edges\u from(MG.selfloop_edges())从多向图中删除自循环时,会生成以下警告: --------------------------------------------------------------------------- RuntimeError Tra
MG.remove_edges\u from(MG.selfloop_edges())
从多向图中删除自循环时,会生成以下警告:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-13-ff3391f2296f> in <module>()
1 # remove selfloop edges from the graph
----> 2 MG.remove_edges_from(MG.selfloop_edges())
~/Program_Files/miniconda3/envs/py36/lib/python3.6/site-packages/networkx/classes/multigraph.py in remove_edges_from(self, ebunch)
603 []
604 """
--> 605 for e in ebunch:
606 try:
607 self.remove_edge(*e[:3])
~/Program_Files/miniconda3/envs/py36/lib/python3.6/site-packages/networkx/classes/function.py in <genexpr>(.0)
1154 return ((n, n)
1155 for n, nbrs in G.adj.items()
-> 1156 if n in nbrs for d in nbrs[n].values())
1157 else:
1158 return ((n, n) for n, nbrs in G.adj.items() if n in nbrs)
~/Program_Files/miniconda3/envs/py36/lib/python3.6/_collections_abc.py in __iter__(self)
759
760 def __iter__(self):
--> 761 for key in self._mapping:
762 yield self._mapping[key]
763
RuntimeError: dictionary changed size during iteration
此方法与有向图的预期效果一样,如下所示:
# create an empty MultiDiGraph
G = nx.DiGraph()
# add some edges to the graph
G.add_edges_from([(1, 2), (2, 3), (3, 1), (1, 2), (2, 1), (2, 2)])
# check the edges in the graph
G.edges
OutEdgeView([(1, 2), (2, 3), (2, 1), (2, 2), (3, 1)])
# remove selfloop edges from the graph
G.remove_edges_from(G.selfloop_edges())
# check the edges in the graph
G.edges()
OutEdgeView([(1, 2), (2, 3), (2, 1), (3, 1)])
问题在于,
MG.selfloop_edges()
是图中selfloop边上的迭代器(更精确地说是生成器),通过删除边,您在迭代过程中更改了迭代器的边
根据报告:
参数:ebunch(边元组的列表或容器)-
这意味着ebunch
参数应该是一个容器,而MG.selfloop\u edges()
返回一个生成器。你可以阅读更多关于两者区别的内容
通过将
列表(MG.selfloop\u edges())
传递给MG.remove\u from
(而不是直接传递MG.selfloop\u edges()
)可以解决这个问题。我在这里的另一个答案中解决了这个问题:
现在您可以执行
MG.从(列表(MG.selfloops\u edges())
中删除边。但是,这实际上是一个bug,将在即将发布的版本中修复:。然后你想写的代码就可以工作了。因为你总是在里面放一个图,我怀疑有bug,除非OP误用了库。它必须在Python2中工作,因此可能在3的端口上没有捕获到它。文档说明ebunch
应该是一个列表或容器,这里传递了一个生成器。因此,至少根据文档,它失败是可以的。然而,与直觉相反的是,原来的代码不起作用,可以很容易地在内部修复。谢谢。我会在你的答案中加上这个(最好是doclink),因为这会把意思从“这里有一个解决方法:…”改为“你用错了”;)谢谢@AndrasDeak,我在下面添加了一个答案,解释了这一点。但基本上,这是一个bug,一旦您更新networkx,它就会消失。
# create an empty MultiDiGraph
G = nx.DiGraph()
# add some edges to the graph
G.add_edges_from([(1, 2), (2, 3), (3, 1), (1, 2), (2, 1), (2, 2)])
# check the edges in the graph
G.edges
OutEdgeView([(1, 2), (2, 3), (2, 1), (2, 2), (3, 1)])
# remove selfloop edges from the graph
G.remove_edges_from(G.selfloop_edges())
# check the edges in the graph
G.edges()
OutEdgeView([(1, 2), (2, 3), (2, 1), (3, 1)])