我有一个包含自环的NetworkX MultiDiGraph。根据{{3}},这是MultiDiGraph的有效属性。
MultiDiGraph保存有向边。允许自循环。
但是当我尝试使用MG.remove_edges_from(MG.selfloop_edges())
从MultiDiGraph中删除自环时,会生成以下警告:
---------------------------------------------------------------------------
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
我是否缺少从MultliDiGraph中删除自环的方式,或者这是NetworkX的错误?
可再现的示例,显示了意外错误:
import networkx as nx
# create an empty MultiDiGraph
MG = nx.MultiDiGraph()
# add some edges to the graph
MG.add_edges_from([(1, 2), (2, 3), (3, 1), (1, 2), (2, 1), (2, 2)])
# check the edges in the graph
MG.edges()
# remove selfloop edges from the graph
MG.remove_edges_from(MG.selfloop_edges())
此方法可与DiGraph一起使用,如下所示:
# 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)])
答案 0 :(得分:2)
问题在于MG.selfloop_edges()
是图形中自环边上的迭代器(更确切地说是生成器),并且通过删除边来在迭代过程中更改迭代器的边。
参数:ebunch(边缘元组的列表或容器)-...
这意味着ebunch
参数应该是一个容器,而MG.selfloop_edges()
返回一个生成器。您可以详细了解两个here之间的区别。
可以通过将 list(MG.selfloop_edges())
传递给MG.remove_edges_from
(而不是直接传递MG.selfloop_edges()
)来解决此问题。
答案 1 :(得分:1)
我在这里的另一个答案中解决了这个问题:https://stackoverflow.com/a/49428652/2966723
现在您可以执行MG.remove_edges_from(list(MG.selfloops_edges()))
。但是,这实际上是一个错误,将在即将发布的版本https://github.com/networkx/networkx/pull/4080中修复。这样,您要编写的代码就可以使用。