【问题标题】:hash method implementation not working along set() [Python]散列方法实现不适用于 set() [Python]
【发布时间】:2021-06-18 01:38:24
【问题描述】:

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

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)

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

【问题讨论】:

  • 根据您的问题user 中显示的所有代码仅在if user in users_set: 之后的脚本末尾的users_set 中。在这种情况下,永远不能采用第一个 if 分支。也许缺少一些代码来证明您的实际问题。

标签: python python-3.x object hash set


【解决方案1】:

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

为什么?

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

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

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


编辑:Python 从 3.4 开始使用 siphash 作为 str

【讨论】:

    猜你喜欢
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 2021-12-10
    • 2019-02-13
    相关资源
    最近更新 更多