Python - 如何通过第二个参数对Priority Queue进行排序

时间:2014-05-19 10:36:46

标签: python

例如,假设我们要插入以下数据 到优先级队列: (0,3,5) (1,2,7) 我希望按第二个参数排序我的优先级队列,然后按第三个参数排序。

我该怎么做?默认情况下,优先级队列按第一个排序其元素 参数。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

implementation of Queue.PriorityQueue依赖于heappush(),它无法提供处理自定义排序的方法。

您可以继承PriorityQueue并使用一点点黑客来完成这项工作而不会破坏功能:

from queue import PriorityQueue

class CustomPriorityQueue(PriorityQueue):
    def _put(self, item):
        return super()._put((self._get_priority(item), item))

    def _get(self):
        return super()._get()[1]


    def _get_priority(self, item):
        return item[1]

试运行:

>>> q = CustomPriorityQueue(100)
>>> q.put((2, 3, 5))
>>> q.put((2, 5, 5))
>>> q.put((2, 1, 5))
>>> q.put((2, 2, 5))
>>> q.get()
(2, 1, 5)
>>> q.get()
(2, 2, 5)
>>> q.get()
(2, 3, 5)
>>> q.get()
(2, 5, 5)

(请注意,这是python3代码)

答案 1 :(得分:0)

documentation看来优先级队列不支持自定义排序。 一个基本的工作是在元组周围创建一个包装器对象,并在那里设置自定义顺序

class Wrapper(object):
    def __init__(self, source):
        self.source = source

    def __cmp__(self, other):
        if self[1] == other[1]:
            return cmp(self.source, other.source)
        else:
            return cmp(self[1], other[1])

    def __getitem__(self, index):
        return self.source[index]

    def __len__(self):
        return len(self.source)

    def __repr__(self):
        return self.source.__repr__()

这只是一个例子,您应该处理边缘情况,其他对象是元组,列表,空元组和带有一个元素的元组。

答案 2 :(得分:0)

来自documentation for Queue.py

实际上有一个PriorityQueue会自动对队列中的元素进行排序,但通常元素是元组结构(优先级编号,数据)

我在这里写了一些示例代码,Q._pop()具有最小优先级编号的元组:

import Queue

q = Queue.PriorityQueue()

print type(q)
print(q.queue)
q._put((4,'f'))
q._put((1,'c'))
q._put((5, 'a'))
q._put((10, 'b'))
q._put((6, 'd'))
print(q.queue)
q._get()
print(q.queue)
q._put((2,'f'))
print(q.queue)

输出结果为:

<type 'instance'>
[]
[(1, 'c'), (4, 'f'), (5, 'a'), (10, 'b'), (6, 'd')]
[(4, 'f'), (6, 'd'), (5, 'a'), (10, 'b')]
[(2, 'f'), (4, 'f'), (5, 'a'), (10, 'b'), (6, 'd')]

我注意到的一件事是,我们第一次打印q.queue,在我们执行任何_get()之前,它没有显示有序队列,但是一旦我们调用_get(),它总是给出有序的队列。