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

  • Hinzufügen der gleichen Variablen zu einer Liste von Tupeln
  • Ich möchte Tupel auf der Grundlage ähnlicher Attribute gruppieren
  • Ein Tupel zwischen zwei Panels in wxPython
  • Python: Tupel / Wörterbücher als Schlüssel, auswählen, sortieren
  • Sortieren Sie eine Liste von Tupeln nach 2. Element (Integer-Wert)
  • Python: Liste der Dict, falls vorhanden, erhöht einen Dict-Wert, wenn nicht ein neuer Dict angehängt wird
  • Python: Tupel-Indizes müssen ganze Zahlen sein, nicht Str bei der Auswahl aus der MySQL-Tabelle
  • Max zweites Element in Tupel Python
  • 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.