How to override the hash function for integers in python?


I’d like to know if there is a way to override the hash function that are already defined for builtin types like int.
In python the hash of an int gives his own value and i’d like to avoid that in my project.

The hash would be used for a dict, so overriding the hash function that the dict uses could work too (but I don’t think it is possible).

I have tried to create my own function and replace the int hash by that, but it didn’t work.

def my_hash(obj) :
    return hash((obj,))

int.__hash__ = my_hash

The code above gave me the error "TypeError: can’t set attributes of built-in/extension type ‘int’".


I try to do that because I have an instance of the problem that is designed to have a lot of collisions in the hashtable. Such an instance can be created because we know that integers are hashed to themselves.

Here’s the code that generate the instance:

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



So apparently, it is not possible to directly override the int hash function, but it is possible to get around the problem.

One solution (as mentioned by @user2357112 in the comments) is to use the string representation of the integers as key to the dictionary.

Another solution is to create my own integer class that overrides the hash function:

class MyInt(int):
    def __new__(cls, *args, **kwargs):
        return  super(MyInt, cls).__new__(cls, args[0])
    def __hash__(self):
        return hash((super().__hash__(),))

I can then use these instead of regular int in my problem.

This allows me to define the hash function however I want to prevent a collision attack.

Answered By: larticho