I'm using python's Queue.PriorityQueue
, and ran into the following problem: when inserting several elements to the queue which have the same priority, I would expect the queue to serve them in the order of insertion (FIFO). For some reason this is not the case:
>>> from Queue import PriorityQueue
>>>
>>> j1 = (1, 'job1')
>>> j2 = (1, 'job2')
>>> j3 = (1, 'job3')
>>> j4 = (1, 'job4')
>>>
>>> q = PriorityQueue()
>>> q.put(j1)
>>> q.put(j2)
>>> q.put(j3)
>>> q.put(j4)
>>> q.queue
[(1, 'job1'), (1, 'job2'), (1, 'job3'), (1, 'job4')]
>>> q.get()
(1, 'job1')
>>> q.queue
[(1, 'job2'), (1, 'job4'), (1, 'job3')]
As can be seen from the example, the order has been mixed after one get()
.
What's the reason? how to overcome (keep the order of same prio elements)?
EDIT:
I was asked to add an example that shows that q.get()
actually mess things up with the FIFO ordering, so here's an elaborate example:
class Job(object):
def __init__(self, type_, **data):
self.type_ = type_
self.priority = 0 if self.type_ == 'QUIT' else 1
self.data = data
def __cmp__(self, other):
return cmp(self.priority, other.priority)
def __repr__(self):
return 'Job("' + self.type_ + '", data=' + repr(self.data) + ')'
q = PriorityQueue()
q.put(Job('Build'))
q.put(Job('Clean'))
q.put(Job('QUIT'))
q.put(Job('Create'))
q.put(Job('Build'))
q.put(Job('Clean'))
Now I'll dequeue the elements one by one. The expected result: QUIT goes out first, and then the rest, FIFO ordered: Build, Clean, Create, Build, Clean:
>>> q.get()
Job("QUIT", data={})
>>> q.get()
Job("Build", data={})
>>> q.get()
Job("Clean", data={})
>>> q.get()
Job("Build", data={}) # <<---
>>> q.get()
Job("Clean", data={})
>>> q.get()
Job("Create", data={})
python-2.7
tag? It happens in Python 3 as well. – Grounds