python hash table



Quando viene calcolato l'hash di un oggetto python e perché l'hash di-1 è diverso? (2)

È facile vedere l'opzione n. 3 valida per gli oggetti definiti dall'utente. Ciò consente all'hash di variare se si muta l'oggetto, ma se si usa l'oggetto come chiave del dizionario si deve essere sicuri di evitare che l'hash cambierà.

>>> class C:
    def __hash__(self):
        print("__hash__ called")
        return id(self)


>>> inst = C()
>>> hash(inst)
__hash__ called
43795408
>>> hash(inst)
__hash__ called
43795408
>>> d = { inst: 42 }
__hash__ called
>>> d[inst]
__hash__ called

Le stringhe utilizzano l'opzione n. 2: calcolano il valore hash una volta e memorizzano il risultato in cache. Questo è sicuro perché le stringhe sono immutabili, quindi l'hash non può mai cambiare, ma se si sottoclassi str il risultato potrebbe non essere immutabile, quindi il metodo __hash__ verrà chiamato ogni volta di nuovo. Solitamente le tuple sono considerate immutabili, quindi si potrebbe pensare che l'hash possa essere memorizzato nella cache, ma in realtà l'hash di una tupla dipende dall'hash del suo contenuto e potrebbe includere valori mutabili.

Per @max chi non crede che le sottoclassi di str possano modificare l'hash:

>>> class C(str):
    def __init__(self, s):
        self._n = 1
    def __hash__(self):
        return str.__hash__(self) + self._n


>>> x = C('hello')
>>> hash(x)
-717693723
>>> x._n = 2
>>> hash(x)
-717693722

https://src-bin.com

Seguendo this domanda, sono interessato a sapere quando viene calcolato l' hash di un oggetto python?

  1. All'ora __init__ di un'istanza,
  2. La prima volta che __hash__() viene chiamato,
  3. Ogni volta che __hash__() viene chiamato, o
  4. Qualche altra opportunità che potrei perdere?

Questo può variare a seconda del tipo di oggetto?

Perché hash(-1) == -2 mentre altri interi sono uguali al loro hash?


Answer #1

Da here :

Il valore hash -1 è riservato (è usato per segnalare errori nell'implementazione C). Se l'algoritmo hash genera questo valore, usiamo semplicemente -2.

Poiché l'hash di un intero è intero, è appena cambiato.





hash