如何将项目放入优先级队列?

时间:2012-02-15 07:47:30

标签: python queue

在Python文档中,

  

首先检索最低值的条目(最低值条目是sorted(list(entries))[0]返回的条目)。条目的典型模式是格式为元组:(priority_number, data)

似乎队列将按优先级排序,然后是数据,这可能并不总是正确的。假设数据“项目2”在“项目1”之前排队,项目1仍将首先排队。在另一个文档页面heapq中,它建议使用计数器。所以我会存储像entry = [priority, count, task]这样的数据。是不是像

那样
PriorityQueue.put(item, priority)

然后我不需要自己实施订购?

3 个答案:

答案 0 :(得分:32)

如果字符串数据的字母数字排序不合适,只需使用元组的第二项作为次要优先级。当您有多个具有相同优先级的项目时,日期/时间优先级将为您提供一个优先级队列,该队列可以回退到FIFIO队列。这是一些只有次要数字优先级的示例代码。在第二个位置使用日期时间值是一个非常微不足道的变化,但如果你无法使它工作,请随时在评论中戳我。

代码

import Queue as queue

prio_queue = queue.PriorityQueue()
prio_queue.put((2, 8, 'super blah'))
prio_queue.put((1, 4, 'Some thing'))
prio_queue.put((1, 3, 'This thing would come after Some Thing if we sorted by this text entry'))
prio_queue.put((5, 1, 'blah'))

while not prio_queue.empty():
    item = prio_queue.get()
    print('%s.%s - %s' % item)

输出

1.3 - This thing would come after Some Thing if we didn't add a secondary priority
1.4 - Some thing
2.8 - super blah
5.1 - blah

修改

如果您使用时间戳使用日期伪造FIFO作为次要优先级,那么这就是它的样子。我说假,因为它只是近似FIFO,因为彼此非常接近的条目可能不会完全出现FIFO。我添加了一个简短的睡眠,所以这个简单的例子以合理的方式解决。希望这有助于您获得如何获得订单的另一个例子。

import Queue as queue
import time

prio_queue = queue.PriorityQueue()
prio_queue.put((2, time.time(), 'super blah'))
time.sleep(0.1)
prio_queue.put((1, time.time(), 'This thing would come after Some Thing if we sorted by this text entry'))
time.sleep(0.1)
prio_queue.put((1, time.time(), 'Some thing'))
time.sleep(0.1)
prio_queue.put((5, time.time(), 'blah'))

while not prio_queue.empty():
    item = prio_queue.get()
    print('%s.%s - %s' % item)

答案 1 :(得分:29)

据我所知,您所寻找的内容并非开箱即用。无论如何,请注意它并不难实现:

from Queue import PriorityQueue

class MyPriorityQueue(PriorityQueue):
    def __init__(self):
        PriorityQueue.__init__(self)
        self.counter = 0

    def put(self, item, priority):
        PriorityQueue.put(self, (priority, self.counter, item))
        self.counter += 1

    def get(self, *args, **kwargs):
        _, _, item = PriorityQueue.get(self, *args, **kwargs)
        return item


queue = MyPriorityQueue()
queue.put('item2', 1)
queue.put('item1', 1)

print queue.get()
print queue.get()

示例输出:

item2
item1

答案 2 :(得分:0)

我做了这样的事情来完成类似于gfortune的FIFO,但是不需要到处调用time.time():(仅适用于Python 3)

import time
from dataclasses import dataclass, field

@dataclass(order=True)
class PrioritizedItem:
    prio: int
    timestamp: float = field(init=False, default_factory=time.time)
    data: object = field(compare=False)

现在您可以这样做:

import queue

item1 = PrioritizedItem(0, "hello world")
item2 = PrioritizedItem(0, "what ever")
q = queue.PriorityQueue()
q.put(item1)
q.put(item2)

请确保它们将始终以相同顺序提取。