Selon le documentation sur l'heapq La façon de personnaliser l'ordre du tas est de faire en sorte que chaque élément du tas soit un tuple, le premier élément du tuple étant un élément qui accepte les comparaisons Python normales.
Les fonctions du module heapq sont un peu lourdes (puisqu'elles ne sont pas orientées objet), et nécessitent toujours que notre objet heap (une liste heapifiée) soit explicitement passé en premier paramètre. Nous pouvons faire d'une pierre deux coups en créant une classe wrapper très simple qui nous permettra de spécifier un objet key
et présente le tas comme un objet.
La classe ci-dessous conserve une liste interne, où chaque élément est un tuple, dont le premier membre est une clé, calculée au moment de l'insertion de l'élément à l'aide de la fonction key
passé lors de l'instanciation du tas :
# -*- coding: utf-8 -*-
import heapq
class MyHeap(object):
def __init__(self, initial=None, key=lambda x:x):
self.key = key
self.index = 0
if initial:
self._data = [(key(item), i, item) for i, item in enumerate(initial)]
self.index = len(self._data)
heapq.heapify(self._data)
else:
self._data = []
def push(self, item):
heapq.heappush(self._data, (self.key(item), self.index, item))
self.index += 1
def pop(self):
return heapq.heappop(self._data)[2]
(Le supplément self.index
est d'éviter les conflits lorsque la valeur de la clé évaluée est un tirage et que la valeur stockée n'est pas directement comparable - sinon heapq pourrait échouer avec TypeError)
1 votes
Duplicata possible de stackoverflow.com/questions/679731/min-heap-in-python
0 votes
Duplicata possible de Comment faire pour que heapq évalue le tas à partir d'un attribut spécifique ?