python - 为什么不应该将重复对象添加到我的 Python 集中?

标签 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))

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

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

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

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

最佳答案

您的哈希函数严重无效。 Python 要求您的 __hash__ 函数应该为两个被认为相等的对象返回相同的值,但您的函数却没有。来自object.__hash__ documentation :

The only required property is that objects which compare equal have the same hash value

repr(self) 返回默认表示,它使用对象 ID。它基本上会根据对象标识 返回不同的散列。你也可以这样做:

return hash(id(self))

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

>>> a = Question('foo', 'bar')
>>> b = Question('foo', 'bar')
>>> a == b
True
>>> hash(a) == hash(b)
False

您需要散列您的属性:

return hash(self.title + self.answer)

现在哈希基于告知相等性的相同值。

关于python - 为什么不应该将重复对象添加到我的 Python 集中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28737764/

相关文章:

C++:用于高效插入和检索自定义数据的数据结构

python - python中aws lambda函数的自动化测试

Python:为什么不支持列表和元组之间的比较?

arrays - 给定一个集合 S,找出其和 <= k 的所有最大子集

python - 在将 python 集与自定义对象相交时选择要保留的元素

java - 使用 LinkedHashSet 存储随机数但有重复

Scala:无法设置环境变量

python - 在 word2vec Gensim 中获取二元组和三元组

python - Django翻译和py2exe

python - 方法重载装饰器