2010-03-28 29 views
25

Ho una lista di oggetti che voglio trasformare in un set. I miei oggetti contengono alcuni campi, alcuni dei quali sono o.id e o.area. Voglio che due oggetti siano uguali se questi due campi sono uguali. vale a dire: o1==o2 se e solo se o1.area==o2.area and o1.id==o2.id.Python: come funzionano gli insiemi

Ho provato a sovrascrivere __eq__ e __cmp__ ma ho ricevuto l'errore: TypeError: unhashable instance.

Cosa devo sovrascrivere?

+3

http://docs.python.org/library/stdtypes.html#set-types-set-frozenset e http://docs.python.org/glossary.html#term-hashable –

risposta

38

Definire il metodo __hash__ per restituire un hash significativo basato sui campi id e area. Es .:

def __hash__(self): 
    return hash(self.id)^hash(self.area) 
+13

Sono un po ' sospettoso di matematica a caso su qualcosa del genere. Vorrei usare qualcosa come = return hash ((self.id, self.area)) =. –

+1

È probabile che si tratti di un problema durante l'hashing di due componenti simili. Ad esempio hash (x)^hash (y) si comporterebbe male se le coordinate delle coordinate con gli assi scambiati sono comuni. In questo caso, è estremamente improbabile che causi problemi poiché è impossibile generare ints e stringhe con hash correlati. Detto questo, il tuo suggerimento è ancora valido, cosa a cui avrei voluto pensare :-). –

9

"TipoErrore: istanza non selezionabile." l'errore è probabilmente dovuto al vecchio stile definizione di classe cioè .:

class A: 
    pass 

Usa stile nuovo, invece:

class A(object): 
    pass 

Se si ignora __cmp__ funzione dovrebbe esclusione __hash__ per utilizzare il vostro oggetto nel set. Nell'altro caso, l'hash considera tutte le istanze dell'oggetto come non uguali e la funzione __cmp__ non verrà mai chiamata.