Most answers suggest this is because of different platforms, but there is more to it. From the documentation of object.__hash__(self)
:
By default, the __hash__()
values of str
, bytes
and
datetime
objects are “salted” with an unpredictable random value.
Although they remain constant within an individual Python process,
they are not predictable between repeated invocations of Python.
This is intended to provide protection against a denial-of-service
caused by carefully-chosen inputs that exploit the worst case
performance of a dict insertion, O(n²) complexity. See
http://www.ocert.org/advisories/ocert-2011-003.html for details.
Changing hash values affects the iteration order of dicts
, sets
and other mappings. Python has never made guarantees about this
ordering (and it typically varies between 32-bit and 64-bit builds).
Even running on the same machine will yield varying results across invocations:
$ python -c "print(hash('http://stackoverflow.com'))"
-3455286212422042986
$ python -c "print(hash('http://stackoverflow.com'))"
-6940441840934557333
While:
$ python -c "print(hash((1,2,3)))"
2528502973977326415
$ python -c "print(hash((1,2,3)))"
2528502973977326415
See also the environment variable PYTHONHASHSEED
:
If this variable is not set or set to random
, a random value is used
to seed the hashes of str
, bytes
and datetime
objects.
If PYTHONHASHSEED
is set to an integer value, it is used as a fixed
seed for generating the hash()
of the types covered by the hash
randomization.
Its purpose is to allow repeatable hashing, such as for selftests for
the interpreter itself, or to allow a cluster of python processes to
share hash values.
The integer must be a decimal number in the range [0, 4294967295]
.
Specifying the value 0
will disable hash randomization.
For example:
$ export PYTHONHASHSEED=0
$ python -c "print(hash('http://stackoverflow.com'))"
-5843046192888932305
$ python -c "print(hash('http://stackoverflow.com'))"
-5843046192888932305