【问题标题】:set custom node equality comparison in networkx [duplicate]在networkx中设置自定义节点相等比较[重复]
【发布时间】:2025-12-15 22:50:03
【问题描述】:

我正在使用 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 或更好的方法来做到这一点。

【问题讨论】:

  • 你还需要实现__hash__...
  • @jonrsharpe 你认为这与networkx无关吗?
  • 是的,问题只是你试图将不可散列的对象放入需要可散列对象的数据结构中,因此你需要实现__hash__

标签: python-3.x networkx


【解决方案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 相等)相同的东西,因此它不会将第二个节点添加到图中。

【讨论】:

  • 到目前为止一切顺利!谢谢!