2010-10-17 13 views

risposta

30

heapq sorta oggetti allo stesso modo list.sort fa, quindi basta definire un metodo __cmp__() all'interno della definizione di classe, che si metterà a confronto a un'altra istanza della stessa classe:

def __cmp__(self, other): 
    return cmp(self.intAttribute, other.intAttribute) 

Lavori in Python 2.x.

In uso 3.x:

def __lt__(self, other): 
    return self.intAttribute < other.intAttribute 
+4

'__cmp__' è andato in 3.x. Usa invece '__lt__'. –

+7

'__lt__' funziona anche in Python 2, quindi è meglio evitare del tutto' __cmp__'. –

+8

Proprio come si può dire qualsiasi ordinamento in base a un criterio diverso dall'ordinamento naturale dell'oggetto (ad esempio 'cmp' e' chiave' per 'sort'), si dovrebbe essere in grado di dire' heapq' per ordinare in base a un chiave diversa. In altre parole, non è necessario * ridefinire l'oggetto stesso * per modificare una particolare struttura di dati che la trattiene; dovresti essere in grado di dire solo la struttura dati stessa. Questo è un pezzo fondamentale notevole mancante dall'API 'heapq'. –

3

Sfortunatamente, non è possibile, anche se questa è una caratteristica spesso richiesta.

Un'opzione consisterebbe nell'inserire tuple (chiave, valore) nell'heap. Tuttavia, ciò non funzionerà se i valori generano un'eccezione quando confrontati (saranno confrontati nel caso di un legame tra le chiavi).

Una seconda opzione sarebbe quella di definire un metodo __lt__ (minore di) nella classe che utilizzerà l'attributo appropriato per confrontare gli elementi per l'ordinamento. Tuttavia, ciò potrebbe non essere possibile se gli oggetti sono stati creati da un altro pacchetto o se è necessario confrontarli in modo diverso altrove nel programma.

Una terza opzione consiste nell'utilizzare la classe sortedlist dal modulo blist (dichiarazione di non responsabilità: sono l'autore). Il costruttore per accetta un parametro key che consente di specificare una funzione per restituire la chiave di ordinamento di un elemento, simile al parametro key di list.sort e sorted.

+0

Ho rimosso il mio commento precedente poiché il mio problema con 'blist' era probabilmente un PEBCAK (ancora grazie per il modulo), quindi duplo solo la prima parte del commento precedente: è sempre possibile definire una classe con un' __lt__ 'tramite sottoclasse o tramite incapsulamento. – tzot

23

Secondo l'esempio dal documentation, è possibile utilizzare tuple, e sarà ordinare dal primo elemento della tupla:

>>> h = [] 
>>> heappush(h, (5, 'write code')) 
>>> heappush(h, (7, 'release product')) 
>>> heappush(h, (1, 'write spec')) 
>>> heappush(h, (3, 'create tests')) 
>>> heappop(h) 
(1, 'write spec') 

Così se non si desidera (o non si può?) fare un metodo __cmp__, è possibile estrarre manualmente la chiave di ordinamento all'ora push.

Si noti che se i primi elementi in una coppia di tuple sono uguali, verranno confrontati ulteriori elementi. Se questo non è ciò che desideri, devi assicurarti che ogni primo elemento sia unico.

Problemi correlati