Python 在NetworkX中按属性检索节点时出现问题

Python 在NetworkX中按属性检索节点时出现问题,python,dictionary,networkx,graph-theory,dictionary-comprehension,Python,Dictionary,Networkx,Graph Theory,Dictionary Comprehension,我正在使用NetworkX开发一个代码,其中有一个类似于以下内容的多部分图: 每个节点都具有以下属性: 图层:它是指可以找到节点的图形列 标签:对于每个列,我为每个节点指定一个标签 轨迹:它是节点之间的关系。如果一个节点与另一个节点相关,则这些节点的标签可能不同,但共享相同的轨迹 在上面的照片中,每个节点标签被描述为“label.layer”(在这种情况下,我们可以看到一个较大图形的子集,因此层编号从451开始,而不是从0开始) 我想从这个图中得到的是单独的字典,这些字典应该只包含属于同一

我正在使用NetworkX开发一个代码,其中有一个类似于以下内容的多部分图:

每个节点都具有以下属性:

  • 图层:它是指可以找到节点的图形列
  • 标签:对于每个列,我为每个节点指定一个标签
  • 轨迹:它是节点之间的关系。如果一个节点与另一个节点相关,则这些节点的标签可能不同,但共享相同的轨迹
在上面的照片中,每个节点标签被描述为“label.layer”(在这种情况下,我们可以看到一个较大图形的子集,因此层编号从451开始,而不是从0开始)

我想从这个图中得到的是单独的字典,这些字典应该只包含属于同一轨迹的节点,也就是说,所有彼此相邻的节点。到目前为止,我关注这些帖子,我的解决方案是:

用于范围内的i(轨迹):
sel_nodes=dict((节点,属性['traction'])用于节点,属性位于G.nodes().items()中,如果属性['traction']==i)
打印(选择节点)
这应该为每个“行”节点返回一个字典,但是输出如下:

{'0.451': 0, '0.452': 0, '0.453': 0, '0.454': 0, '0.455': 0, '0.456': 0, '0.457': 0, '0.458': 0, '0.459': 0, '0.460': 0}
{'1.451': 1, '1.452': 1, '1.453': 1, '1.454': 1, '1.455': 1, '1.456': 1, '1.457': 1, '1.458': 1, '1.459': 1, '1.460': 1}
{'2.451': 2, '3.452': 2, '3.453': 2, '3.454': 2, '3.455': 2, '3.456': 2, '3.457': 2, '3.458': 2, '3.459': 2, '4.460': 2}
{'3.451': 3, '2.452': 3, '2.453': 3, '2.454': 3, '2.455': 3, '2.456': 3, '2.457': 3, '2.458': 3, '2.459': 3, '3.460': 3}
{'4.451': 4, '4.452': 4, '4.453': 4, '4.454': 4, '4.455': 4, '4.456': 4, '4.457': 4, '4.458': 4, '4.459': 4, '5.460': 4}
{'5.451': 5, '5.452': 5, '5.453': 5, '5.454': 5, '5.455': 5, '5.456': 5, '5.457': 5, '5.458': 5, '5.459': 5, '6.460': 5}
{'6.451': 6, '6.452': 6, '6.453': 6, '6.454': 6, '6.455': 6, '6.456': 6, '6.457': 6, '6.458': 6, '6.459': 6, '7.460': 6}
{'7.451': 7, '7.452': 7, '7.453': 7, '7.454': 7, '7.455': 7, '7.456': 7, '7.457': 7, '7.458': 7, '7.459': 7, '8.460': 7}
{'8.451': 8, '8.452': 8, '8.453': 8, '8.454': 8, '8.455': 8, '8.456': 8, '8.457': 8, '8.458': 8, '8.459': 8, '9.460': 8}
{}
{}
最后两个空dict应该分别包含图的下一行节点和最后一列的孤独节点,但事实并非如此,我只能检索以某种方式连接到第一列的节点

有没有办法纠正这种行为

编辑:为了稍微缩小问题的范围,我相信问题在于我使用的字典理解,因为我已经通过执行以下操作检查属性轨迹是否具有指定的值:

print(G.nodes['9.455']['tracept']

输出给我轨迹9,这与我期望的轨迹一致。

我觉得这里的DICT列表是错误的数据结构。看起来你真正想要的是一个数据结构,它告诉你,给定一个轨迹
i
,哪些节点属于这个轨迹?一份集合的目录或集合的列表似乎更合适

下面是如何在一个小示例图上构建这样一个列表,其中顶部轨迹是一个孤立的节点,底部两个相互交叉:

>>将networkx导入为nx
>>>G=nx.Graph()
>>>G.add_nodes_from([(0.3,{“轨迹”:0}),(1.1,{“轨迹”:1}),(2.2,{“轨迹”:1}),(2.3,{“轨迹”:1}),(2.1,{“轨迹”:2}),(1.2,{“轨迹”:2}),(1.3,{“轨迹”:2})])
>>>从集合导入defaultdict
>>>d=默认DICT(设置)
>>>对于节点,G.nodes().items()中的属性:
...     d[attrs[“轨迹”].添加(节点)
... 
>>>d
defaultdict(,{0:{0.3},1:{1.1,2.2,2.3},2:{1.2,2.1,1.3})
如果您确实想要如上所述的DICT列表,您可以从这里轻松构建它:

>>> for trajectory, nodes in d.items():
...     print({node: trajectory for node in nodes})
... 
{0.3: 0}
{1.1: 1, 2.2: 1, 2.3: 1}
{1.2: 2, 2.1: 2, 1.3: 2}
如果希望每个轨迹都有一个有序列表,而不是一个集合,则可以根据名称小数点后的部分进行排序:

>>d={k:sorted(nodes,key=lambda x:str(x)[2:])对于k,d.items()中的节点
>>>d
{0: [0.3], 1: [1.1, 2.2, 2.3], 2: [2.1, 1.2, 1.3]}

非常感谢,它工作得非常好。我对Python比较陌生,老实说,我不知道集合是什么,但它们似乎是我计划的更好的解决方案。我能看到的唯一缺点是集合是无序的,而且由于我的图表显示了某种时间进程,因此,如果能让我对它进行排序,以便以后分析de子集,那就太好了。但我肯定能找到一个解决方案。使用命名方案,可以很容易地将集合转换为列表,从而为每个轨迹提供有序的节点序列。用一个例子更新了我的答案。太棒了!我想理解Python是实现很多事情的关键。。。我想我应该学习它是如何工作的,因为我不知道它有多强大。再次感谢你的回答。