散列方法实现无法与 set() [Python] 一起工作

hash method implementation not working along set() [Python]

我正在一个对象中实现一个散列函数,我使用用户名散列值作为该对象的散列值,即:

class DiscordUser:
    def __init__(self, username):
        self.username = username

    def __hash__(self):
        return hash(self.username)

将此类对象添加到哈希集并将它们与与构造函数输入完全相同的用户名进行比较时会出现问题,即:

user = DiscordUser("Username#123")

if user in users_set:
    # user is already in my users_set, such condition is NEVER MET, dont understand why

else:
    # add user to users_set, this condition is met ALWAYS
    users_set.add(user)

为什么哈希函数不能正常工作,或者我做错了什么?

哈希函数正常工作,set成员使用__hash__(),但如果两个对象具有相同的哈希,set将使用__eq__()方法来确定它们是否相等。最终,set 保证没有两个元素是相等的,而不是没有两个元素具有相等的哈希值。哈希值用作第一遍,因为它的计算成本通常低于相等性。

为什么?

不能保证具有相同散列值的任何两个对象实际上是相等的。考虑到您的 `DiscordUser` 中的 `self.name` 有无限个值。 Python 使用 siphash 散列 `str` 值。 Siphash 有一个有限的范围,因此碰撞必须是可能的。

使用可变值作为 hash() 的输入时要小心。一个对象的哈希值在其生命周期内应该是相同的。

查看此 answer,了解有关 Python 中的 set、散列和相等性测试的一些有用信息。


编辑:自 3.4

起,Python 使用 siphash 作为 str