2012-12-21 7 views
7

Sulla console ho digitatopitone dizionario enigma

>>> 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'> 

ho pensato in un primo momento che il motivo che d tenuto solo una coppia era perché hash(a) e hash(b) restituito gli stessi valori, così ho provato:

>>> 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>} 

Ora sono confuso. Come mai nella prima lista di codici, d ha mantenuto solo una coppia, ma nella seconda lista d entrambe le chiavi sono state mantenute nonostante abbiano lo stesso hash?

risposta

8

I due oggetti nell'esempio originale sono stati compressi non perché hanno lo stesso hash, ma perché sono uguali. Le chiavi Dict sono uniche per quanto riguarda l'uguaglianza , non l'hash. Python richiede che qualsiasi due oggetti che si confrontano uguali deve avere lo stesso hash (ma non necessariamente il contrario).

Nel primo esempio, i due oggetti sono uguali, poiché entrambi hanno il comportamento di uguaglianza str. Poiché i due oggetti sono uguali, sono ridotti a uno. Nel secondo esempio, non sono uguali. Per default le classi definite dall'utente usano l'identità per l'uguaglianza --- cioè, ogni oggetto è paragonabile solo a se stesso. Quindi i tuoi due oggetti non sono uguali. Non importa che abbiano lo stesso hash.

0

I tasti sono diversi per il primo e il secondo oggetto. Poiché sono oggetti, la chiave è un equivalente leggibile dell'oggetto e non una stringa.

4

L'hash non determina la chiave univoca in un dizionario. In qualche modo, le funzioni di hash sono un "dettaglio di implementazione", in quanto determinano come il dizionario memorizza internamente le sue voci. a == b implica hash (a) == hash (b), ma l'inverso non vale in generale. Anche due chiavi devono essere uguali tra loro (quando si applica l'operatore ==) per essere trattate come chiavi equivalenti in un dizionario.

Problemi correlati