You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中重写int等内置类型的哈希函数?

如何规避Python中int哈希值等于自身导致的哈希冲突?

核心结论

Python的内置类型(如int)的特殊方法(包括__hash__)是受语言层面保护的,无法直接修改属性——这就是你执行int.__hash__ = my_hash时触发TypeError的原因,CPython不允许修改内置扩展类型的属性。

可行解决方案

方案1:用自定义包装类封装int

创建一个轻量包装类,将int值包裹起来,重写__hash__和__eq__方法,既实现自定义哈希逻辑,又保证键的相等性判断符合dict的要求。

示例代码:

class WrappedInt:
    def __init__(self, value):
        self.value = int(value)
    
    def __eq__(self, other):
        # 支持与同类实例或原生int的相等判断
        if isinstance(other, WrappedInt):
            return self.value == other.value
        return self.value == other
    
    def __hash__(self):
        # 替换为你需要的哈希逻辑,比如你最初尝试的tuple哈希
        return hash((self.value,))
    
    # 可选:添加调试友好的字符串表示
    def __repr__(self):
        return f"WrappedInt({self.value})"

适配你的场景使用:

t, n = 1, 2 * 10 ** 5
mask = (1 << 17) - 1
fill = int((1 << 15) * 1.3 + 1)
arr = []
arr += [WrappedInt(mask + 2)] * 2
x = 6
for i in range(1, fill):
    arr += [WrappedInt(x)] + [WrappedInt(x)]
    x = x * 5 + 1
    x = x & mask
arr += [WrappedInt(1)] * (n - len(arr))

后续将这些WrappedInt实例作为dict的键,就会使用自定义哈希逻辑,分散原int集中的哈希值,减少冲突。

方案2:自定义哈希映射类(替代原生dict)

如果不想修改所有int的使用方式,可以实现一个模拟dict行为的类,对int类型键单独应用自定义哈希逻辑。注意:此方案需要额外处理键的相等性判断,避免不同键因哈希碰撞被误判为同一键。

示例代码:

class CustomHashDict:
    def __init__(self):
        self._inner_dict = {}
    
    def _get_hash(self, key):
        if isinstance(key, int):
            return hash((key,))
        # 非int类型保留原生哈希逻辑
        return hash(key)
    
    def __setitem__(self, key, value):
        # 用(哈希值, 原键)作为内部存储的键,避免哈希碰撞导致的键冲突
        self._inner_dict[(self._get_hash(key), key)] = value
    
    def __getitem__(self, key):
        target_hash = self._get_hash(key)
        for stored_hash, stored_key in self._inner_dict:
            if stored_hash == target_hash and stored_key == key:
                return self._inner_dict[(stored_hash, stored_key)]
        raise KeyError(key)
    
    def __contains__(self, key):
        target_hash = self._get_hash(key)
        for stored_hash, stored_key in self._inner_dict:
            if stored_hash == target_hash and stored_key == key:
                return True
        return False

注意:该方案的查找性能会弱于原生dict,适合数据量不大或无法修改原有int使用逻辑的场景。

补充说明

你的测试代码生成的整数会因mask限制和生成逻辑,集中在特定数值范围内,而int哈希等于自身的特性会导致dict哈希表出现大量冲突。使用包装类方案可以从根源上改变这些值的哈希分布,彻底解决冲突问题。

内容的提问来源于stack exchange,提问作者larticho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:02:50