0

I was trying out the python3 in-built hash() method for arbitrary values, then ranges, and I saw something funny:

>>> [hash(i) for i in range(-20,20)]
[-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

The hash value produced for integers is usually the integer itself, except for -1, which, for some reason, is -2, as is that of -2 as well.

My Python3 interpreter is:

Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux

This can be replicated elsewhere, too, such as repl.it, which produced:

Python 3.6.1 (default, Dec 2015, 13:05:11)
[GCC 4.8.2] on linux
hash(1)
=> 1
[hash(i) for i in range(-20,20)]
=> [-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]   

<iframe height="400px" width="100%" src="https://repl.it/@aalok_sathe/FairCornflowerblueLadybug?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

I understand that hashing may produce collisions, and if at all this is a case of collision, I did not expect it to happen on this small a scale. I'm looking for anything that could help explain this behavior, and any tips on what alternatives/workarounds could be used when I actually need to use this in a program (one that I can think of is converting integers to strings and then hashing, but that would not allow for different types having different hash values). The application specifics aside, I'm just puzzled by this so any pointer would help.

axolotl
  • 1,042
  • 1
  • 12
  • 23
  • Why would you need a workaround? Python dicts handle collision resolution automatically, like pretty much any other general-use hash table implementation. – user2357112 Feb 09 '18 at 00:51
  • Hashes are *by design* allowed to be equal to another object’s hash. If you need unique hashes for something, you are doing it wrong. – poke Feb 09 '18 at 00:53
  • @poke I understand that, but wouldn't one expect _small_ integers to have distinguishable hash values, especially if they appear to be in a pattern? – axolotl Feb 09 '18 at 00:55
  • 1
    Well, the pattern is very simple: All integers hash to themselves, except -1. And no, you generally shouldn’t have any expectations for hash values. They are an implementation detail which you should not build upon. – poke Feb 09 '18 at 00:59

0 Answers0