在networkx中设置自定义节点相等性比较

时间:2016-01-11 22:04:30

标签: python-3.x networkx

我正在使用python3和networkx来构建图形。 Networkx真的很棒,但是我想说我想把一些好的对象放在节点中。这是我的对象制作者(一个简单的类,为了演示目的):

class DictToObject:
    def __init__(self, dic):
        for key, value in dic.items():
            setattr(self, key, value)
    def __eq__(self, other):
        return self.id == other.id

然后是一些节点:

import networkx

s1 = DictToObject({"name":"sarah", "id":"s"})
s2 = DictToObject({"name":"sarah", "id":"s"})

M = networkx.DiGraph()
M.add_edge(s1, s2)

由于覆盖__eq__,我收到错误:

Traceback (most recent call last):
  File "networkxcapabilitytest.py", line 16, in <module>
    M.add_edge(s1, s2)
  File "/usr/local/lib/python3.4/site-packages/networkx/classes/digraph.py", line 485, in add_edge
    if u not in self.succ:
TypeError: unhashable type: 'DictToObject'

这令人非常沮丧。覆盖__eq__似乎是让networkx识别何时应将两个节点视为“相同”的“正确”方法。也许我应该将此问题提交给networkx开发人员。或者也许有一个内置的networkx或更好的方法。

1 个答案:

答案 0 :(得分:1)

关注@ jonrsharpe的评论:

class DictToObject:
    def __init__(self, dic):
        for key, value in dic.items():
            setattr(self, key, value)
    def __eq__(self, other):
        return self.id == other.id
    def __hash__(self):
        return hash(self.__dict__.values())
    def __repr__(self):
        return str(self.__dict__.values())

import networkx

s1 = DictToObject({"name":"sarah", "id":"s"})
s2 = DictToObject({"name":"sarah", "id":"s"})

M = networkx.DiGraph()
M.add_edge(s1, s2)

print( M.nodes() )
print( M.edges() )

输出:

[dict_values(['s', 'sarah'])]
[(dict_values(['s', 'sarah']), dict_values(['s', 'sarah']))]

请注意,现在图表中只有一个节点。由于hash()生成(id&#39; s)相同的东西,因此它不会将第二个节点添加到图中。