Я могу либо использовать (priority, object)
, как предлагает Чарли Мартин, либо просто реализовать __cmp__
для моего объекта.
Если вы хотите, чтобы вставленные объекты были расположены по приоритетам в соответствии с определенным правилом, я нашел очень полезным написать простой подкласс PriorityQueue
, который принимает функцию ключа. Вам не придется вставлять (priority, object)
кортежи вручную, и обработка будет более естественной.
Демонстрация желаемого поведения :
>>> h = KeyHeap(sum)
>>> h.put([-1,1])
>>> h.put((-1,-2,-3))
>>> h.put({100})
>>> h.put([1,2,3])
>>> h.get()
(-1, -2, -3)
>>> h.get()
[-1, 1]
>>> h.get()
[1, 2, 3]
>>> h.get()
set([100])
>>> h.empty()
True
>>>
>>> k = KeyHeap(len)
>>> k.put('hello')
>>> k.put('stackoverflow')
>>> k.put('!')
>>> k.get()
'!'
>>> k.get()
'hello'
>>> k.get()
'stackoverflow'
Код Python 2
from Queue import PriorityQueue
class KeyHeap(PriorityQueue):
def __init__(self, key, maxsize=0):
PriorityQueue.__init__(self, maxsize)
self.key = key
def put(self, x):
PriorityQueue.put(self, (self.key(x), x))
def get(self):
return PriorityQueue.get(self)[1]
Код Python 3
from queue import PriorityQueue
class KeyHeap(PriorityQueue):
def __init__(self, key, maxsize=0):
super().__init__(maxsize)
self.key = key
def put(self, x):
super().put((self.key(x), x))
def get(self):
return super().get()[1]
Очевидно, что вызов put
вызовет (и должен!) Вызвать ошибку, если вы попытаетесь вставить объект, который ваша ключевая функция не может обработать.