Rastapopoulos
Rastapopoulos

Reputation: 507

Python hash is not deterministic with sympy objects

I am feeding symbolic expressions to a function, and would like to return previously computed results when the set of input arguments has already been treated before. To that purpose, I was thinking of hashing the arguments passed to the function, but this does not work because it seems that hash does not produce determistic results when applied to symbolic expressions. For example, the following code prints values that are always different.

import sympy as sym
x = sym.symbols('x')
print(hash(x))

Is there a way to deterministally hash Sympy symbolic expressions?

Upvotes: 2

Views: 360

Answers (2)

ptb
ptb

Reputation: 2148

You are running into a security feature known as hash randomization.

$ cat hash_test.py 
import sympy as sym
x = sym.symbols('x')
print(hash(x))

A few runs with this simple example:

$ python hash_test.py 
6842375726913792912
$ python hash_test.py 
5041915772945005780
$ python hash_test.py 
-3461975266180802906

Run without hash randomization to get the same results:

$ PYTHONHASHSEED=0 python hash_test.py 
-2285490307665029553
$ PYTHONHASHSEED=0 python hash_test.py 
-2285490307665029553
$ PYTHONHASHSEED=0 python hash_test.py 
-2285490307665029553

Upvotes: 2

gl00ten
gl00ten

Reputation: 1121

From here: http://docs.sympy.org/latest/python-comparisons.html https://docs.python.org/dev/glossary.html#term-hashable

Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id().

def __hash__(self):
    return id(self)

Which I imagine is the reason you are having the different hash, as the instances have a different id.

I hope you can get the comparison you need from the first doc I posted.

Upvotes: 1

Related Questions