Згідно з документацією heapq , спосіб настроїти порядок купи полягає в тому, щоб кожен елемент у купі був кортежем, причому перший елемент кортежу - це той, що приймає звичайні порівняння Python.
Функції в модулі heapq трохи громіздкі (оскільки вони не є об'єктно-орієнтованими), і завжди вимагають явного передавання нашого об'єкта кучі (скручений список) як першого параметра. Ми можемо вбити двох зайців одним каменем, створивши дуже простий клас обгортки, який дозволить нам вказати key
функцію та представити купу як об’єкт.
У наведеному нижче класі зберігається внутрішній список, де кожен елемент - це кортеж, першим членом якого є ключ, обчислений під час вставки елемента за допомогою key
параметра, переданого під час інстанціації Heap:
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]
(Додатковою self.index
частиною є уникнення зіткнень, коли оцінене значення ключа є тиражем, а збережене значення не можна безпосередньо порівняти - інакше heapq може вийти з ладу з TypeError)