使用NetworkX处理有向图时出现KeyError的问题求助
NetworkX有向图冗余节点裁剪KeyError问题排查与修复
核心错误原因
- 遍历已删除节点:你遍历的是初始节点列表
nodes,但循环中会从图里删除节点,当循环到已被删除的节点时,访问g._node[x]会触发KeyError——该节点已不存在于图中。 - 无效节点索引使用:变量
a、b只是计数累加值,不是节点列表的有效索引,用nodes[a]、nodes[b]获取节点完全错误:初始nodes列表不会随图节点删除更新,要么访问到已删除节点,要么直接索引越界。 - 内部属性直接操作:直接访问
g._node是NetworkX的内部实现属性,官方不推荐直接操作,应使用g.nodes[node_id]['node_class']获取节点属性。 - 循环中修改遍历列表:嵌套循环里重复赋值
newlist,会破坏原有遍历逻辑,导致后续迭代处理错误节点。
修复方案与代码示例
正确思路:先收集需要裁剪的节点,同时记录每个冗余节点的前驱和后继,删除冗余节点后将前驱直接连接到后继。调整后的代码如下:
import networkx as nx import functions import matplotlib.pyplot as plt Path_graph = './Output/graphs_graphml/noPCE/DEXPI_Distillation_noMSR.xml' functions.plot_graph2(Path_graph, './Output/graphs_plots') g = nx.read_graphml(Path_graph) # 定义需要裁剪的节点类型集合 CUT_CLASSES = { 'Pipe tee', 'Valve (general)', 'Flap trap (from 2)', 'Funnel', 'Orifice plate', 'Flange' } # 遍历图节点的副本,避免遍历过程中节点删除导致的异常 for node in list(g.nodes): if g.nodes[node]['node_class'] not in CUT_CLASSES: continue # 获取当前冗余节点的所有前驱和后继 predecessors = list(g.predecessors(node)) successors = list(g.successors(node)) # 将所有前驱直接连接到所有后继,重建路径 for pred in predecessors: for succ in successors: g.add_edge(pred, succ) # 删除当前冗余节点 g.remove_node(node) # 可添加后续绘图或保存操作
关键注意事项
- 用
list(g.nodes)创建节点副本遍历,即使图中节点被删除,遍历列表不受影响。 - 裁剪节点前先记录其前驱和后继,确保删除后能正确重建连接,而非依赖错误的计数变量索引。
- 用集合定义需裁剪的节点类型,代码更简洁易维护,避免重复的elif判断。
- 始终使用NetworkX公开API(如
g.nodes[node])访问节点属性,避免依赖内部实现。
内容的提问来源于stack exchange,提问作者GaulSoodman
相关产品推荐
相关产品推荐

