2016-07-14 6 views
3

Ich habe Spyder verwendet, führen Sie Python 2.7.Warum gibt die Hash-Funktion für zwei verschiedene Objekte denselben Wert zurück?

Gerade gefunden interessante Dinge:

  1. Hash (-1) und Hash (-2), die beide -2 zurückkehren, ist es ein Problem? Ich würde zwar Hash-Funktion auf ein anderes Objekt sollte verschiedene Werte zurückgeben. Ich habe vorherige Posts gelesen, dass -1 in Python als Fehler reserviert ist.
  2. Hash ('s') gibt 1835142386 zurück, dann gibt Hash (1835142386) denselben Wert zurück. Ist das ein anderes Problem?

Danke.

+1

"Ich obwohl Hash-Funktion auf anderen Objekt sollte verschiedene Werte zurückgeben" --- Nein, es sollte nur den gleichen Wert für das gleiche Objekt zurückgeben. – zerkms

+0

Hashes garantiert keine Eindeutigkeit. –

+0

Es ist jedoch seltsam, dass anders als -1, "Hash (i) == i" für "abs (i) <= 1.000.000". – chepner

Antwort

1

-1 ist in Python nicht als Fehler reserviert. Nicht sicher, was das überhaupt bedeuten würde. Es gibt eine große Anzahl von Programmen, die Sie nicht einfach und klar schreiben können, wenn Sie -1 nicht verwenden dürfen.

"Gibt es ein Problem?" Nein. Hash-Funktionen müssen für jedes Objekt keinen anderen Hashwert zurückgeben. In der Tat ist dies nicht möglich, da es viel mehr mögliche Objekte als Hashes gibt. CPythons hat die nette Eigenschaft, sein Argument für nicht-negative Zahlen bis zu sys.maxint zurückzugeben, weshalb in Ihrer zweiten Frage hash(hash('s')) == hash('s'), aber das ist ein Implementierungsdetail.

Die Tatsache, dass -1 und -2 den gleichen Hash haben, bedeutet einfach, dass die Verwendung dieser Werte wie zum Beispiel Dictionary Keys zu einem Hash-Konflikt führt. Hash-Konflikte sind eine erwartete Situation und werden automatisch von Python gelöst, und der zweite Schlüssel hinzugefügt würde einfach in den nächsten verfügbaren Steckplatz im Wörterbuch gehen. Der Zugriff auf den zweiten Schlüssel wäre dann etwas langsamer als der Zugriff auf den anderen Schlüssel, aber in den meisten Fällen nicht genug langsamer, dass Sie bemerken würden.

Es ist möglich, eine große Anzahl ungleicher Objekte mit demselben Hash-Wert zu konstruieren, was bei einer Speicherung in einem Dictionary oder einem Set die Performance des Containers erheblich verschlechtern würde, da jedes hinzugefügte Objekt einen Fehler verursachen würde Hash-Kollision, aber es ist nicht etwas, in das Sie hineinlaufen werden, wenn Sie nicht danach suchen.

+0

Wenn der Wert -1 nicht reserviert ist (für etwas) - was ist der praktische Zweck, dass es eine Ausnahme ist? https://github.com/python/cpython/blob/2d264235f6e066611b412f7c2e1603866e0f7f1b/Python/pyhash.c#L188 – zerkms

+1

Nun, scheint wie es einen Fehler anzeigt: https://github.com/python/cpython/blob/2d264235f6e066611b412f7c2e1603866e0f7f1b/ Python/pyhash.C# L4 "Alle Dienstprogrammfunktionen (_Py_Hash *()) geben" -1 "zurück, um einen Fehler anzuzeigen." – zerkms

+0

Richtig, wenn die Hash-Funktion keine Eindeutigkeit garantiert (was sinnvoll ist, gibt es mehr Objekte als Ganzzahlen), jedes Mal, wenn ich einen neuen Schlüssel hinzufüge, wenn der Hashwert mit einem Wert zurückkehrt, der zufällig der gleiche ist wie der Wert des Schlüssels Das System wird das beheben, oder? Das macht Sinn. Vielen Dank. –