2012-12-21 12 views
7

auf der Konsole eingegeben ich inPython Wörterbuch conundrum

>>> class S(str): pass 
... 
>>> a = 'hello' 
>>> b = S('hello') 
>>> d = {a:a, b:b} 
>>> d 
{'hello': 'hello'} 
>>> type(d[a]) 
<class '__main__.S'> 
>>> type(d[b]) 
<class '__main__.S'> 

Ich dachte zuerst, dass der Grund, dass d nur ein Paar gehalten war, weil hash(a) und hash(b) die gleichen Werte zurück, so dass ich versuchte:

>>> class A(object): 
...  def __hash__(self): 
...    return 0 
... 
>>> class B(object): 
...  def __hash__(self): 
...    return 0 
... 
>>> d = {A():A(),B():B()} 
>>> d 
{<__main__.A object at 0x101808b90>: <__main__.A object at 0x101808b10>, <__main__.B object at 0x101808d10>: <__main__.B object at 0x101808cd0>} 

Jetzt bin ich verwirrt. Wie kommt es in der ersten Code-Liste, d nur ein Paar gehalten, aber in der zweiten Auflistung d beide Schlüssel wurden gehalten, trotz der gleichen Hash?

Antwort

8

Die beiden Objekte in Ihrem ursprünglichen Beispiel wurden nicht zusammengebrochen, weil sie denselben Hashwert haben, sondern weil sie gleich sind. Dict-Schlüssel sind einzigartig in Bezug auf Gleichheit, nicht Hash. Python erfordert, dass zwei Objekte, die den gleichen Wert haben, denselben Hashwert haben müssen (aber nicht unbedingt umgekehrt).

In Ihrem ersten Beispiel sind die beiden Objekte gleich, da sie sowohl die str Gleichheit Verhalten haben. Da die beiden Objekte gleich sind, sind sie auf Eins reduziert. Im zweiten Beispiel vergleichen sie nicht gleich. Standardmäßig verwenden benutzerdefinierte Klassen die Identität für die Gleichheit, dh jedes Objekt vergleicht nur dasselbe mit sich selbst. Deine zwei Objekte sind also nicht gleich. Es spielt keine Rolle, dass sie den gleichen Hash haben.

0

Die Schlüssel sind für das erste und zweite Objekt unterschiedlich. Da sie Objekte sind, ist der Schlüssel ein lesbares Äquivalent des Objekts, kein String.

4

Der Hash bestimmt nicht den eindeutigen Schlüssel in einem Wörterbuch. In gewisser Weise sind Hash-Funktionen ein "Implementierungsdetail", da sie bestimmen, wie das Wörterbuch seine Einträge intern speichert. a == b impliziert hash (a) == hash (b), aber die Umkehrung gilt im Allgemeinen nicht. Zwei Schlüssel müssen auch einander gleich sein (wenn der Operator == angewendet wird), um als äquivalente Schlüssel in einem Wörterbuch behandelt zu werden.