liste als key in dictionary
Oeh. Doch. Da der hashwert ueber die Inhalte berechnet wird, ist eine Liste eben nicht hashbar. Also ist das schon das gleiche. Natuerlich kann "man", wenn man will, immer einen hash definieren. Python aber macht es nicht. Darum ist es in dem Kontext schon das gleiche.
Python macht es so, wie es der Programmierer programmiert.__deets__ hat geschrieben: Freitag 28. Oktober 2022, 17:18 Oeh. Doch. Da der hashwert ueber die Inhalte berechnet wird, ist eine Liste eben nicht hashbar. Also ist das schon das gleiche. Natuerlich kann "man", wenn man will, immer einen hash definieren. Python aber macht es nicht. Darum ist es in dem Kontext schon das gleiche.
Dass der hash bei Python durch den Inhalt bestimmt wird, stimmt ja offensichtlich nicht, dazu gab es in diesem Thread schon Beispiele.
Natürlich wird er das. Und was sollen diese Beispiele gewesen sein? Das rumgefummelt an einer Liste im Tupel? Das ist kein Gegenbeispiel. Denn das Tupel ist dann nicht hashbar, und konsequenterweise auch nicht als Schlüssel verwendbar.
Natürlich rede ich hier über die Standardtypen und Datenstrukturen. Wer will, kann natürlich durch Überladung der entsprechenden Operatoren pathologisches Verhalten erzeugen. Darum gehts aber nicht.
Edit: warum auch immer, jetzt erst deinen Post genau zu den eigenen Typen gesehen. Ja, da kann man das dann natürlich mischen.
Natürlich rede ich hier über die Standardtypen und Datenstrukturen. Wer will, kann natürlich durch Überladung der entsprechenden Operatoren pathologisches Verhalten erzeugen. Darum gehts aber nicht.
Edit: warum auch immer, jetzt erst deinen Post genau zu den eigenen Typen gesehen. Ja, da kann man das dann natürlich mischen.
Deinen letzten Absatz hatte ich überlesen: Bei eigenen Klassen kannst Du das schon so umsetzen, bei den Python builtin-Datatypes ist dies aber nicht der Fall, daher scheiden von diesen die Mutablen als keys aus.bords0 hat geschrieben: Donnerstag 27. Oktober 2022, 18:04 Es geht letztlich nicht um mutability sondern um hashability. Also mutable darf es schon sein, solange es auch hashable ist.
Mit selbst definierten Klassen kann man das durchaus machen. Es ist nach meiner Erfahrung aber nur selten sinnvoll.
Aber Du schreibst auch, dass dies nach Deiner Erfahrung nur selten sinnvoll sei.
Ich halte dies auch nicht für sinnvoll, denn dann wäre ein hash quasi eine id. Über einen hash aber sollte sich in Erfahrung bringen lassen, ob sich das Objekt selbst geändert hat. Im Grunde basieren alle Anwendungen, die hashs verwenden, auf dieser Annahme.
Sorry, das sollte kein Suchspiel sein für ein Beispiel, wo der Hashwert nicht vom Inhalt bestimmt wird. Ich meinte @__blackjacks__ Beispiel mit object(), die keinen Inhalt haben, aber trotzdem immer einen anderen Hashwert.__deets__ hat geschrieben: Freitag 28. Oktober 2022, 18:31 Und was sollen diese Beispiele gewesen sein?
viewtopic.php?p=412080#p412080
Und ja, die Standardtypen in Python sind nicht hashable, wenn sie mutable sind, und wenn sie immutable sind, sind sie hashable (es sei denn, sie enthalten nicht-hashable Elemente). (Es könnte von letzterem Ausnahmen geben, mir fallen aber keine ein.)
Deshalb ist dort immutable und hashable das gleiche, und da braucht man dann nicht weiterdiskutieren.
Technisch reicht es, wenn ein Objekt einen Haswert hat, damit man es in ein set oder dict stecken kann. Auch wenn der "pathologisch" definiert ist. Sinnvoll ist das eher nicht, und das wollte ich auch nicht behaupten. Darüber brauchen wir auch nicht diskutieren.
Ich glaube eigentlich, dass wir alle fast das gleiche meinen. Vielleicht kommen wir weiter, wenn wir noch mal anschauen, was wir unter "mutable" verstehen. Für mich ist im folgenden Beispiel a mutable.
Code: Alles auswählen
>>> class A:
def __init__(self, x):
self.x = x
>>> a = A(10)
>>> a.x
10
>>> a.x = 20
>>> a.x
20
>>> vars(a)
{'x': 20}
>>> a.y = 300
>>> vars(a)
{'x': 20, 'y': 300}
Das stimmt natuerlich so, und das liegt daran, dass bei einem x-beliebigen Objekt einer solch simplen Klasse hash und Vergleichsoperator von der Identitaet abhaengen. Es kann nie zwei Objekte an der gleichen Stelle im Speicher geben, also geht das. Und natuerlich ist das mutable, aber es kann nicht im Speicher bewegt werden, zerbricht also nichts.
Nur ist das natuerlich schon ein sehr spezieller Fall: es gibt nur *einen* Schluessel, sie alles zu knechten. Das hat gelegentlich mal seine Anwendung, aber mein mentaler Rahmen fuer die Diskussion waren Schluessel wie im TE-Beispiel, die komponiert sind, und deren hash und Vergleichbarkeit sich an ihrem eigenen Inhalt orientiert. Und die man auch erzeugen kann (zB aus einem Web-Request), und dann auch was aus dem Woerterbuch raus bekommt. Also sowas hier.
Und da eben nachtraeglich den Schluessel zu veraendern, so das der nicht mehr auffindbar ist, das ist ein in meinen Augen pathologisches Verhalten. Das siehst du aber denke ich genauso, ich habe einfach nur nicht sauber genug die Argumente gelesen, und deinen einen Satz daher nicht im richtigen Kontext interpretiert.
Nur ist das natuerlich schon ein sehr spezieller Fall: es gibt nur *einen* Schluessel, sie alles zu knechten. Das hat gelegentlich mal seine Anwendung, aber mein mentaler Rahmen fuer die Diskussion waren Schluessel wie im TE-Beispiel, die komponiert sind, und deren hash und Vergleichbarkeit sich an ihrem eigenen Inhalt orientiert. Und die man auch erzeugen kann (zB aus einem Web-Request), und dann auch was aus dem Woerterbuch raus bekommt. Also sowas hier.
Code: Alles auswählen
class Foo:
def __init__(self, *a):
self._content = tuple(a)
def __hash__(self):
return hash(self._content)
def __eq__(self, other):
return self._content == other._content
foo1 = Foo(1, 2, 3)
foo2 = Foo(1, 2, 3) # wir tun mal so, als ob foo2 aus einer irgendwie gearteten Suchanfrage kommt
assert foo1 == foo2
d = { foo1: "hallo" }
print(d[foo2])
foo1._content = (3, 4, 5)
print(d[foo2])
Da möchte ich einmal anknüpfen: ist "a" wirklich mutabel? Oder ist nicht vielmehr "a.__dict__" mutabel?bords0 hat geschrieben: Samstag 29. Oktober 2022, 10:23 Wenn also a mutable ist (da magst du anderer Meinung sein, das fände ich interessiert), so ist es doch auch hashable und z.B. problemlos als key in dicts und sets zu verwenden. Ich sehe kein pathologisches Verhalten und keine Überladung von Operatoren. Es ist einfach das Standardverhalten von Python.
Nein, diese pauschale Interpretation liegt mir fern. Tatsächlich ist „a“ immutabel und es kommt in diesem Fall auf die Kombination und Implementierung von __eq__ und __hash__ an (hattest Du gezeigt) und nicht darauf, ob die Instanz oder deren Attribute mutabel sind. Nachdem ich das Data Model von Python noch einmal nachgeschlagen habe, muss ich board0 recht geben: die hashability ist entscheidend, nicht die mutability. Die Python Doku weist aber auch darauf hin, was man tunlichst unterlassen sollte, um bucket-misses zu vermeiden. Wenn man nicht so weit in die Tiefe geht, ist die Aussage, keine mutablen Datentypen als keys verwenden zu können, aber völlig praxisgerecht.