2010-10-17 13 views

Répondre

30

heapq sortes objets de la même manière list.sort ne, définir si juste une méthode __cmp__() au sein de votre définition de classe, qui se compare à une autre instance de la même classe:

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

Works en Python 2.x.

En utilisation 3.x:

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

'__cmp__' est parti dans 3.x. Utilisez '__lt__' à la place. –

+7

'__lt__' fonctionne aussi en Python 2, donc il vaut mieux éviter complètement' __cmp__'. –

+8

Tout comme vous pouvez trier n'importe quel tri en fonction d'un critère autre que le tri naturel de l'objet (par exemple, 'cmp' et' key' pour 'sort'), vous devriez pouvoir dire à' heapq' de trier en fonction d'un clé différente. En d'autres termes, vous ne devriez pas avoir à * redéfinir l'objet lui-même * pour modifier une structure de données particulière qui le contient; vous devriez être capable de simplement dire la structure de données elle-même. C'est une pièce fondamentale notable manquante dans l'API 'heapq'. –

3

Malheureusement, vous ne pouvez pas, bien que ce soit une fonctionnalité souvent demandée.

Une option consisterait à insérer des tuples (clé, valeur) dans le tas. Cependant, cela ne fonctionnera pas si les valeurs lancent une exception lorsqu'elles sont comparées (elles seront comparées en cas d'égalité entre les clés).

Une deuxième option consisterait à définir une méthode __lt__ (inférieure à) dans la classe qui utilisera l'attribut approprié pour comparer les éléments à trier. Cependant, cela peut ne pas être possible si les objets ont été créés par un autre paquet ou si vous avez besoin de les comparer différemment ailleurs dans le programme.

Une troisième option consisterait à utiliser la classe sortedlist du module blist (avertissement: je suis l'auteur). Le constructeur pour sortedlist prend un paramètre key qui vous permet de spécifier une fonction pour renvoyer la clé de tri d'un élément, similaire au paramètre key de list.sort et sorted.

+0

J'ai supprimé mon commentaire précédent puisque mon problème avec 'blist' était probablement un PEBCAK (encore merci pour votre module), donc je ne fais que dupliquer la première partie du commentaire précédent: Il est toujours possible de définir une classe avec un' __lt__ 'soit par sous-classe ou par encapsulation. – tzot

23

Selon l'exemple de la documentation, vous pouvez utiliser tuples, et il trier par le premier élément du tuple:

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

Alors Si vous ne voulez pas (ou ne pouvez pas?) faire une méthode __cmp__, vous pouvez extraire manuellement votre clé de tri au moment du push.

Notez que si les premiers éléments d'une paire de tuples sont égaux, d'autres éléments seront comparés. Si ce n'est pas ce que vous voulez, vous devez vous assurer que chaque premier élément est unique.