Почему python3 выдает одинаковое значение хэша для -1 и -2?

Я пробовал python3 встроенный hash() метод для произвольных значений, затем диапазонов, и я увидел что-то смешное:

>>> [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]

Значение хеша, создаваемое для целых чисел, обычно представляет собой само целое число, за исключением -1, которое по некоторым причинам равно -2, как и значение -2.

Мой интерпретатор Python3:

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

Это можно повторить и в другом месте, например, repl.it, который выдает:

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>

Я понимаю, что хеширование может привести к коллизиям, и если это вообще коллизия, я не ожидал, что это произойдет в таком маленьком масштабе. Я ищу что-нибудь, что могло бы помочь объяснить это поведение, и любые советы о том, какие альтернативы / обходные пути можно использовать, когда мне действительно нужно использовать это в программе (один из тех, о которых я могу подумать, - это преобразование целых чисел в строки и затем хэширование, но это не позволило бы различным типам иметь разные значения хеша). Если не учитывать специфику приложения, я просто озадачен этим, так что любой указатель поможет.

0 ответов

Другие вопросы по тегам