Comment faire heapq évaluer le tas hors d'un attribut spécifique?
Je souhaite organiser un tas d'objets, pas seulement des chiffres. Ils ont un attribut entier en eux que le tas peut trier par. La façon la plus simple d'utiliser des tas de python est heapq, mais comment dois-je le dire à trier par un attribut spécifique lors de l'utilisation de heapq?
Vous devez vous connecter pour publier un commentaire.
heapq
sortes d'objets de la même façonlist.sort
n', il suffit donc de définir une méthode__cmp__()
au sein de votre définition de classe, ce qui permettra de comparer lui-même à une autre instance de la même classe:Œuvres en Python 2.x.
En 3.x utilisation:
__cmp__
est parti en 3.x. Utilisation__lt__
à la place.__lt__
œuvres en Python 2 aussi, il est donc préférable de simplement les éviter__cmp__
tout à fait.cmp
etkey
poursort
), vous devez être en mesure de direheapq
de tri basé sur une clé différente. En d'autres termes, vous ne devriez pas avoir à redéfinir l'objet lui-même pour modifier les données particulières de la structure de holding, vous devriez être en mesure de simplement dire la structure de données elle-même. C'est un notable fondamentaux de l'élément manquant de laheapq
API.Selon l'exemple de la la documentation, vous pouvez utiliser les tuples, et il va trier par le premier élément du tuple:
Donc, si vous ne voulez pas (ou ne peuvent pas?) faire un
__cmp__
méthode, vous pouvez extraire manuellement votre clé de tri à pousser de temps.Noter que si les premiers éléments d'une paire de n-uplets 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.
(some_value, dict)
, vous pouvez insérer(some_value, counter, dict)
dans le tas de rompre les liens avec une incrémentation du compteur en cassome_value
est égale pour les 2 tuples.Selon la Document Officiel, une solution consiste à stocker des entrées comme des n-uplets (veuillez consulter les Sections 8.4.1 et 8.4.2).
Par exemple, votre objet est quelque chose comme cela dans tuple's format
(clé, valeur_1, value_2)
Quand vous mettez les objets (c'est à dire tuples) dans tas, il va comparer le premier attribut de l'objet (dans ce cas, est clé) pour comparer. Si une égalité se produit, tas testaments utiliser l'attribut suivant (c'est à dire valeur_1) et ainsi de suite.
Par exemple:
De sortie:
Sur à peu l'impression d'un tas en python (mis à jour le lien): show_tree()
show_tree()
lien ne fonctionne plus.Malheureusement, vous ne pouvez pas, même si c'est souvent une demande de fonctionnalité.
Une option consisterait à insérer (clé, valeur) de n-uplets dans le tas. Toutefois, cela ne fonctionnera pas si les valeurs de lever une exception au regard (ils seront comparés dans le cas d'une égalité entre les touches).
Une deuxième option serait de définir un
__lt__
(moins) de la méthode dans la classe qui utilisent l'attribut approprié pour comparer les éléments pour le tri. Toutefois, cela pourrait ne pas être possible si les objets ont été créés par un autre paquet ou si vous avez besoin de comparer différemment ailleurs dans le programme.Une troisième option serait d'utiliser la sortedlist classe à partir de la blist module (disclaimer: je suis l'auteur). Le constructeur de
sortedlist
prend unkey
paramètre vous permet de spécifier une fonction de retourner la clé de tri d'un élément, semblable à lakey
paramètre delist.sort
etsorted
.blist
était probablement un PEBCAK (encore une fois merci pour votre module), donc je ne copie la première partie du commentaire précédent: Il est toujours possible de définir une classe avec un__lt__
soit par le biais de sous-classement ou par l'intermédiaire de l'encapsulation.Vous pourriez mettre en œuvre un heapdict. Notez l'utilisation de popitem() pour obtenir la priorité la plus basse de l'élément.