[Python-Dev] Priority queue (binary heap) python code
Skip Montanaro
skip@pobox.com
Mon, 24 Jun 2002 23:09:32 -0500
Kevin> I don't explicitly associate a priority with every item in the
Kevin> queue - instead I rely on the user having a __cmp__ operator
Kevin> defined on the items (if the default does not suffice).
That's what I missed.
>> Seems to me that you could implement the type of priority queue I'm
>> think of rather easily using a class that wraps a list of Queue.Queue
>> objects. Am I missing something obvious?
Kevin> Perhaps I am, because I do not see how one would use Queue.Queue
Kevin> efficiently for this task.
I don't know how efficient it would be, but I usually think that most
applications have a small, fixed set of possible priorities, like ("low",
"medium", "high") or ("info", "warning", "error", "fatal"). In this sort of
situation my initial inclination would be to implement a dict of Queue
instances which corresponds to the fixed set of priorities, something like:
import Queue
class PriorityQueue:
def __init__(self, priorities):
self.queues = {}
self.marker = Queue.Queue()
self.priorities = priorities
for p in priorities:
self.queues[p] = Queue.Queue()
def put(self, obj, priority):
self.queues[priority].put(obj)
self.marker.put(None)
def get(self):
dummy = self.marker.get()
# at this point we know one of the queues has an entry for us
for p in self.priorities:
try:
return self.queues[p].get_nowait()
except Queue.Empty:
pass
if __name__ == "__main__":
q = PriorityQueue(("low", "medium", "high"))
q.put(12, "low")
q.put(13, "high")
q.put(14, "medium")
print q.get()
print q.get()
print q.get()
Obviously this won't work if your set of priorities isn't fixed at the
outset, but I think it's pretty straightforward, and it should work in
multithreaded applications. It will also work if for some reason you want
to queue up objects for which __cmp__ doesn't make sense.
Skip