为什么在不应该的情况下将重复的对象添加到我的 Python 集中?

Rea*_*ues 3 python set

我对此有一个类定义:

class Question:
    title = ""
    answer = ""
    def __init__(self, title, answer):
            self.title = title
            self.answer = answer
    def __eq__(self, other):
            return self.title == other.title and self.answer == other.answer
    def __hash__(self):
        return hash(repr(self))
Run Code Online (Sandbox Code Playgroud)

我尝试将其中许多对象添加到集合中,前提是该对象不具有与集合中已有的任何其他对象相同的属性:

        questionset = set()
        q = Question(questionparts[0] + questionparts[1], questionparts[2])
        if q not in questionset:
            questionset.add(q)
Run Code Online (Sandbox Code Playgroud)

如果我有两个问题,每个问题都具有相同的属性值,我希望只有一个问题添加到我的集合中,而我的集合的长度为 2。

我究竟做错了什么?如果我记录每个问题对象,我可以确认这些项目具有相同的属性值。

Mar*_*ers 6

你的哈希函数非常无效。Python 要求您的__hash__函数应该为两个被视为相等的对象返回相同的值,但您的函数却不然。从object.__hash__文档中:

唯一需要的属性是比较相等的对象具有相同的哈希值

repr(self)返回默认表示,它使用对象 id。它基本上会根据对象身份返回不同的哈希值。您也可能已经这样做了:

return hash(id(self))
Run Code Online (Sandbox Code Playgroud)

这不是一个好的哈希值,因为所有实例之间的值都不同。因此,您的hash()值无法满足所需的属性:

>>> a = Question('foo', 'bar')
>>> b = Question('foo', 'bar')
>>> a == b
True
>>> hash(a) == hash(b)
False
Run Code Online (Sandbox Code Playgroud)

您需要对属性进行哈希处理:

return hash(self.title + self.answer)
Run Code Online (Sandbox Code Playgroud)

现在,哈希值基于表示相等性的相同值。