Hashable, unveränderlich
Aus einer aktuellen Frage ALSO (siehe Erstellen Sie ein Wörterbuch in python, die indiziert ist, die mit Listen) ich merkte, ich hatte wohl eine falsche Vorstellung von der Bedeutung von hashable und unveränderliche Objekte, die in python.
- Was bedeutet hashable in der Praxis bedeuten?
- Was ist die Beziehung zwischen hashable und immmutable?
- Gibt es veränderliche Objekte, die hashable oder unveränderliche Objekte, die nicht hashable?
InformationsquelleAutor joaquin | 2010-04-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hashing ist der Prozess der Umwandlung einige große Menge von Daten in einen viel kleineren Betrag (in der Regel eine einzelne Ganzzahl) in reproduzierbarer Weise, so dass es sein kann, schaute in einer Tabelle in konstanter Zeit (
O(1)
), die wichtig ist für die high-performance-algorithmen und Datenstrukturen.Unveränderlichkeit ist die Idee, dass ein Objekt nicht verändern wird in einigen wichtigen Weg, nachdem es erstellt wurde, vor allem in einer Weise, die möglicherweise ändern Sie den hash-Wert des Objekts.
Beide Ideen beziehen, da Objekte, die als hash-Schlüssel müssen in der Regel unveränderlich sind, so dass deren hash-Wert ändert sich nicht. Wenn es erlaubt war, das zu ändern, dann ist die Lage des Objekts in eine Datenstruktur wie ein Hash ändern würde und dann der ganze Zweck des hashing für die Effizienz ist besiegt.
Wirklich zu begreifen die Idee, die Sie sollten versuchen, zu implementieren Ihre eigenen hashtable in einer Sprache wie C/C++, oder Lesen Sie die Java-Implementierung des
HashMap
Klasse.HashMap
wird gebrochen, wenn Sie ändern ein Objekt als Schlüssel verwendet: weder der alte noch der neue Schlüssel kann gefunden werden, obwohl, wenn Sie drucken Sie die Karte, es kann es gesehen werden.Hashable und Unveränderlich sind etwas verwandt, aber nicht identisch. E. g. Erzeugten Instanzen von benutzerdefinierten Klassen Erben
object
sind hashable aber nicht unveränderlich. Diese Instanzen können verwendet werden, hat die Schlüssel des dict, aber Sie können noch geändert werden, wenn Sie herum.InformationsquelleAutor maerics
In Python Tupel unveränderlich ist, aber es ist hashable nur, wenn alle seine Elemente sind hashable.
Hashable Arten
InformationsquelleAutor liuyihe
Technisch, hashable bedeutet, dass die Klasse definiert
__hash__()
. Laut der docs:Ich denke, dass für die Python-builtin-Typen, alle hashable-Typen sind auch unveränderlich.
Es schwer werden würde, aber vielleicht nicht unmöglich, haben ein veränderliches Objekt, die dennoch definiert
__hash__()
.__hash__
ist standardmäßig definiert das Objekt zurückzugeben istid
; Sie gehen aus dem Weg, um__hash__ = None
zu machen unhashable. Auch als Mark Lösegeld erwähnt, gibt es eine zusätzliche Bedingung, dass es nur hashable, wenn der hash-Wert kann sich niemals ändern!Ich denke, die Antwort ist ein wenig irreführend,
list
definiert__hash__
in dem Sinne, dasshasattr([1,2,3], "__hash__")
zurückTrue
jedoch Berufunghash([1,2,3])
wirft eineTypeError
(Python 3), so ist es nicht gerade hashable. Unter Berufung auf die Existenz__hash__
ist nicht ausreichend, um zu bestimmen, ob etwas eine) hashable b) unveränderlichInformationsquelleAutor Andrew Jaffe
Aus der Python-Glossar:
Dicts und Sätze müssen, verwenden Sie einen hash für die effiziente Suche in einer hash-Tabelle; die hash-Werte sind unveränderlich, weil die änderung der hash wird mess up der Daten, Strukturen und bewirken, dass das dict-oder scheitern. Der einfachste Weg, um den hash-Wert, der unveränderlich ist, um das gesamte Objekt unveränderlich ist, weshalb die beiden oft gemeinsam erwähnt.
Während keiner der built-in-mutable-Objekte sind hashable, ist es möglich, ein veränderliches Objekt mit einem hash-Wert, der nicht verändert werden. Es ist üblich, dass nur ein Teil des Objektes zu repräsentieren, seine Identität, während der rest der das Objekt enthält Eigenschaften, die frei sind, sich zu ändern. Solange die hash-Wertes und Vergleich-Funktionen basieren auf der Identität, nicht aber die änderbaren Eigenschaften, und die Identität, die sich nie ändert, Sie habe den Anforderungen entsprochen.
frozenset
s, richtig? 🙂frozensets sind hashable, setzt nicht; beide können nur enthalten hashable Elemente. In den Orten, die von Mark erwähnten sets, er war richtig, also ich glaube nicht, dass er gemeint frozensets.
Benutzer-definierte Klassen standardmäßig definieren hashable-Typen (der hash ist nur das Objekt
id
). Dies kann nicht ändern, während das Objekt ist Leben, so ist es hashable, aber das bedeutet nicht, Sie können nicht definieren, veränderliche Arten! Sorry, aber hashability bedeutet nicht Unveränderbarkeit.Ich weiß nicht, warum es dauerte 6 Jahre, um zu sehen Ihren Kommentar, aber besser spät als nie. Ich weiß nicht, wie ich hätte so weit Weg, da habe ich beklagt die Unfähigkeit zu setzen mutable-Objekte in einem C++ gesetzt. Ich hoffe, dass meine änderung behebt Dinge.
InformationsquelleAutor Mark Ransom
Gibt es eine implizite, auch wenn es keine explizite Beziehung gezwungen, zwischen unveränderlichen und hashable durch das zusammenspiel zwischen
Hier gibt es kein problem, es sei denn, Sie definieren
__eq__
so das die Objekte der Klasse definiert äquivalenz auf Wert.Sobald Sie dies getan haben, benötigen Sie eine stabile hash-Funktion gibt immer den gleichen Wert für Objekte, die den gleichen Wert (zB, wo
__eq__
) gibt True zurück, und ändert sich nie während der Lebensdauer eines Objekts.Es schwer zu sehen, eine Anwendung, wo dies möglich ist, ziehen Sie einen möglichen Klasse Eine, der diese Anforderungen erfüllt. Obwohl es die offensichtlich degenerierten Fall, wo
__hash__
gibt eine Konstante.Nun:-
In der Tat bedeutet dies die Schaffung hash(b) == hash(c), trotz der Tatsache, dass es nie im Vergleich gleich. Ich Kämpfe, um zu sehen, sowieso sinnvoll definieren
__hash__
() für ein veränderliches Objekt, das definiert, vergleichen von Wert.Hinweis:
__lt__
,__le__
,__gt__
und__ge__
comparsions sind nicht betroffen, so können Sie noch definieren eine Reihenfolge von hashable Objekte veränderlich oder sonst auf Ihren Wert.InformationsquelleAutor rgammans
nur weil das ist die top-Google-Treffer, hier ist ein einfacher Weg, um ein veränderliches Objekt hashable:
Ich fand sogar eine Verwendung für so etwas wie diese bei der Erstellung einer Klasse zu casten Datensätze in SQLAlchemy etwas wandelbar ist, und mehr nützlich für mich, während die Aufrechterhaltung der hashability für den Einsatz als dict-Schlüssel.
InformationsquelleAutor jcomeau_ictx
Immutable bedeutet, dass das Objekt nicht ändern, in irgendeiner signifikanten Art und Weise während seiner Lebensdauer. Es ist eine vage, aber gemeinsame Idee in Programmiersprachen.
Hashability ist etwas anders, und bezieht sich auf den Vergleich.
Alle benutzerdefinierten Klassen haben
__hash__
- Methode, die standardmäßig nur die Renditen der Objekt-ID. Also ein Objekt, das den Kriterien entspricht, die für hashability ist nicht unbedingt unveränderlich.Objekte von jeder neuen Klasse, die Sie deklarieren können verwendet werden als dictionary-Schlüssel, es sei denn, Sie verhindern, dass es zum Beispiel durch das werfen von
__hash__
Könnten wir sagen, dass alle unveränderliche Objekte sind hashable, denn wenn sich der hash ändert, während das Objekt Leben, dann bedeutet es, dass das Objekt mutiert.
Aber nicht ganz. Betrachten wir ein Tupel, welches eine Liste (änderbar). Einige sagen, Tupel unveränderlich ist, aber zur gleichen Zeit es ist etwas nicht hashable (wirft).
Hashability und Unveränderlichkeit siehe Objekt instancess, nicht geben. Zum Beispiel, ein Objekt vom Typ tuple werden kann hashable oder nicht.
Es ist möglich, solche Objekte, aber es wäre ein Verstoß gegen ein Konzept definiert, in der Python-Dokumentation. Die Idee ist, dass, in der Tat, wir können diese Forderung abzuleiten, eine solche (logisch äquivalent) Implikation: Wenn die Hashwerte nicht gleich sind, dann werden die Objekte nicht gleich sind. Sehr nützlich sind. Viele Implementierungen, die Container und algorithmen verlassen sich auf diese Implikation die Dinge etwas beschleunigen.
In häufigen Fällen, wo
comparison != identity
ist beim Vergleich von "ungültigen" Werte zusammen wiefloat("nan") == float("nan")
oder interniert strings von Scheiben:"apple" is "apple"
vs."apple" is "crabapple"[4:]
InformationsquelleAutor user2622016
In der Python-Sie sind meistens austauschbar, da der hash darstellen soll, der Inhalt, also es ist genauso wandelbar ist wie das Objekt, und ein Objekt ändern Sie den hash-Wert machen es unbrauchbar, weil ein dict-key.
In anderen Sprachen, wird der hash-Wert bezieht sich auf die Objekte 'Identität', und nicht (unbedingt) auf den Wert. Also, für ein veränderliches Objekt, das Zeiger verwendet werden könnten, um starten Sie den hashing. Vorausgesetzt natürlich, dass ein Objekt nicht verschieben, die in Speicher (wie einige GC). Dies ist der Ansatz, die in der Lua, zum Beispiel. Dies macht ein veränderliches Objekt nutzbar als Tisch-Schlüssel; aber es erzeugt einige (unangenehme) überraschungen für Neulinge.
Am Ende, mit einer unveränderlichen Sequenz-Typ (Tupel) macht es schöner für 'multi-value-Tasten'.
InformationsquelleAutor Javier
Hashable bedeutet, dass eine variable, die den Wert der dargestellt werden kann (oder, eher, Sat), die durch eine ständige-string, Anzahl, etc. Nun, etwas, das verändert werden (veränderlich) kann nicht dargestellt werden durch etwas, das nicht ist. Also, alle Variablen, die verändert werden kann hashable und, durch die gleichen token, die nur unveränderliche Variablen können hashable.
Hoffe, das hilft ...
InformationsquelleAutor ktdrv