List unhashable, aber Tupel hashable?

In Wie Hash-Listen? Mir wurde gesagt, dass ich zuerst in ein Tupel umwandeln sollte, zB [1,2,3,4,5] bis (1,2,3,4,5) .

Also das erste kann nicht gehastet werden, aber das zweite kann. Warum?


* Ich bin nicht wirklich auf der Suche nach einer ausführlichen technischen Erklärung, sondern eher für eine Intuition

  • Elegantes Auspacken variabler Länge Tupel
  • Erstellen Sie eine Liste von Tupeln aus zwei verschachtelten Listen
  • Fügen Sie Variablen zu Tupel hinzu
  • Wie man einen Text in Tupel in einer Liste in Python umwandelt
  • Finden Sie doppelte Elemente in einer Liste der Liste der Tupel Python
  • Gib ein Tupel von Argumenten zurück, die an string.format ()
  • Tupel Vergleich
  • Warum brauchen wir Tupel in Python (oder jedem unveränderlichen Datentyp)?
  • 4 Solutions collect form web for “List unhashable, aber Tupel hashable?”

    Hauptsächlich, weil Tupel unveränderlich sind. Nehmen wir folgende Arbeiten an:

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

    Nun, was passiert, wenn du l.append(4) ? Du hast den Schlüssel in deinem Wörterbuch geändert! Von weit weg! Wenn Sie vertraut sind, wie Hash-Algorithmen funktionieren, sollte dies Sie erschrecken. Tupel, auf der anderen Seite, sind absolut unveränderlich. t += (1,) könnte aussehen wie es das Tupel zu ändern, aber wirklich ist es nicht: es einfach das Erstellen eines neuen Tupels, so dass Ihr Wörterbuch Schlüssel unverändert.

    Du könntest diese Arbeit total machen, aber ich wette, du würdest die Effekte nicht mögen.

     from functools import reduce from operator import xor class List(list): def __hash__(self): return reduce(xor, self) 

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

    Bearbeiten: Also habe ich darüber nachgedacht? Sie könnten das obige Beispiel machen, wenn Sie die ID der ID als Hash-Wert zurückgeben:

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

    In diesem Fall wird dir d[l] dir 'Hello' , aber weder d[[23,42,99,7]] noch d[List([23,42,99,7])] wird (weil du " Eine neue [Ll]ist .

    Da eine Liste veränderlich ist, wenn du sie modifizierst, würdest du auch ihren Hash ändern, was den Hash-Punkt (wie in einem Satz oder einem Dict-Schlüssel) ruiniert.

    Denn Listen sind veränderlich und Tupel sind nicht.

    Python ist die beste Programmiersprache der Welt.