我不熟悉在Python中使用队列,最近我开始使用PriorityQueue。
我期待根据优先级编号将元素插入队列中。也就是说,如果我做了类似的事情:
from Queue import PriorityQueue
q = PriorityQueue()
q.put((1, '1'))
q.put((4, 'last'))
q.put((2, '2'))
q.put((3, '3'))
print q.queue
我期待这个输出:
[(1, '1'), (2, '2'), (3, '3'), (4, 'last')].
相反,我得到:
[(1, '1'), (3, '3'), (2, '2'), (4, 'last')]
但是,如果我通过以下方式将元素从队列中取出:
while not q.empty():
item = q.get()
print item
我确实得到了我期望的输出:
(1, '1')
(2, '2')
(3, '3')
(4, 'last')
我试图通过在某些点打印队列来调试某些东西,并注意到这些元素不符合我的预期。除非我错过了,否则Queue的文档没有提及有关排序的任何内容。期望它被分类是我错了吗?可能因为效率原因而没有以这种方式实施吗?
答案 0 :(得分:3)
不应该对优先级队列进行排序。优先级队列仅保证在您调用get()
时,它会返回优先级最高的项目。
在内部,queue.PriorityQueue
使用binary heap来包含项目。
它没有使用排序数组的原因是因为维护排序数组很昂贵。添加和删除项目将是O(n)操作。二进制堆进行那些O(log n)操作。
有关详细信息,请参阅https://github.com/python/cpython/blob/2.7/Lib/Queue.py和https://docs.python.org/2/library/heapq.html。
答案 1 :(得分:1)
它是有序的,但是堆的顺序。 PriorityQueue
由堆实现。
q.queue
只是一个简单的列表,但每次插入一个元素时,它都会进行堆移位。
您可以测试visualization website。当你插入(3, '3')
时,它会看到它比它的父节点(4, 'last')
小,所以它们将被交换。