wake-up-neo.com

Liste unhashable, aber tuple hashable?

In How to Listen Mir wurde gesagt, dass ich zuerst in ein Tuple konvertieren sollte, z. [1,2,3,4,5] bis (1,2,3,4,5).

So kann der erste nicht gehasht werden, der zweite kann. Warum*?


*Ich suche nicht wirklich eine detaillierte technische Erklärung, sondern eher eine Intuition

20
gsamaras

Hauptsächlich, weil Tupel unveränderlich sind. Nehmen Sie die folgenden Arbeiten an:

>>> l = [1, 2, 3]
>>> t = (1, 2, 3)
>>> x = {l: 'a list', t: 'a Tuple'}

Was passiert nun, wenn Sie l.append(4) tun? Sie haben den Schlüssel in Ihrem Wörterbuch geändert! Von weit weg! Wenn Sie mit der Funktionsweise von Hash-Algorithmen vertraut sind, sollte dies Sie erschrecken. Tupel dagegen sind absolut unveränderlich. t += (1,) könnte so aussehen, als würde er den Tuple modifizieren, aber im Grunde ist es nicht so: Er erstellt einfach ein new Tuple, wobei der Wörterbuchschlüssel unverändert bleibt.

35
val

Sie könnten diese Arbeit komplett machen, aber ich wette, Sie würden die Effekte nicht mögen.

from functools import reduce
from operator import xor

class List(list):
    def __hash__(self):
        return reduce(xor, self)

Mal sehen was passiert:

>>> l = List([23,42,99])
>>> hash(l)
94
>>> d = {l: "Hello"}
>>> d[l]
'Hello'
>>> l.append(7)
>>> d
{[23, 42, 99, 7]: 'Hello'}
>>> l
[23, 42, 99, 7]
>>> d[l]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: [23, 42, 99, 7]

edit: Also dachte ich noch etwas darüber nach. Das obige Beispiel könnte funktionieren, wenn Sie die ID der Liste als Hashwert zurückgeben:

class List(list):
    def __hash__(self):
        return id(self)

In diesem Fall erhalten Sie d[l] zwar 'Hello', aber weder d[[23,42,99,7]] noch d[List([23,42,99,7])] (da Sie einen neuen [Ll]ist erstellen.).

7
L3viathan

Da eine Liste veränderbar ist, ändern Sie auch ihren Hash, wenn Sie sie modifizieren. Dadurch wird der Punkt eines Hash (wie in einem Satz oder einem Diktierschlüssel) ruiniert.

4
polku

Weil Listen veränderlich sind und Tupel nicht.

4
Daniel Roseman

Die Antworten sind gut. Der Grund ist die Wandelbarkeit. Wenn wir Liste in Diktaten als Schlüssel verwenden könnten; (oder ein beliebiges veränderliches Objekt), dann können wir den Schlüssel durch zufälliges oder absichtliches Verändern dieses Schlüssels ändern. Dies würde zu einer Änderung des Hashwerts des Schlüssels im Wörterbuch führen, aufgrund dessen wir den Wert aus dieser Datenstruktur nicht durch diesen Schlüssel zurückverfolgen könnten. Hash-Werte und Hash-Tabellen werden verwendet, um die großen Daten auf einfache Weise abzubilden, indem sie den Indizes zugeordnet werden, in denen die echten Werte gespeichert werden. 

Lesen Sie hier mehr darüber: - 

Hash-Tabellen & Hash-Funktionen & Assoziative Arrays

1
Vicrobot

Nicht jedes Tuple ist hashbar. Zum Beispiel enthält Tuple list als Element.

x = (1,[2,3])
print(type(x))
print(hash(x))
0
user1436465