在python中如何颠倒优先级队列的顺序?

在python中如何颠倒优先级队列的顺序?,python,queue,priority-queue,Python,Queue,Priority Queue,我在python中创建了一个简单的优先级队列,它根据项目的值对项目进行排序: import Queue q = Queue.PriorityQueue() for it in items: q.put((it.value, it)) 但当我使用以下命令打印队列时: while not q.empty() print q.get() 它总是先打印最低值。是否有一种方法可以获取队列中的最后一项,而不将代码顶部的最后两行更改为: for it in items: q.put

我在python中创建了一个简单的优先级队列,它根据项目的值对项目进行排序:

import Queue
q = Queue.PriorityQueue()
for it in items:
    q.put((it.value, it))
但当我使用以下命令打印队列时:

while not q.empty()
    print q.get()
它总是先打印最低值。是否有一种方法可以获取队列中的最后一项,而不将代码顶部的最后两行更改为:

for it in items:
    q.put((-1*it.value, it))
因为这看起来有点混乱,如果我想将这些信息用于其他用途(我必须再次将其乘以-1),就会产生问题。

根据(假设python 2.7):


那就意味着,不,你不能

根据定义,您只能从队列前面检索项目。要颠倒顺序,可以将所有内容都推到堆栈上,然后从堆栈中弹出项目。由于堆栈同时从其背面添加和检索项目,因此这与反转队列具有相同的效果。

对于
queue.PriorityQueue

首先检索值最低的条目(值最低的条目是排序(列表(条目))[0]返回的条目)


因此,您可以尝试
queue.LifoQueue
。它是
LIFO
机制。

您可以使转换透明化

您想要的是有一个新的
q.get
和一个新的
q.put
,它可以透明地修改队列中的数据和队列外的数据,使其顺序相反:

# new reversed priority put method
q.oldput = q.put
q.put = lambda p, i: q.oldput((p * -1, i))

# new reversed priority get method
q.oldget = q.get
# create get closure for queue
def newget(q):
    def g():
        item = q.oldget()
        # reverse first element
        return item[0] * -1, item[1]
    # return get method for given queue
    return g
# bind to queue
q.get = newget(q)

# test
items = range(10)
for it in items:
    q.put(*(it, it))

while not q.empty():
    print q.get()
如果要使代码更健壮,我强烈建议使用类,而不仅仅是重新绑定方法。

您可以创建自己的类,该类继承自PriorityQueue,并在后台为您执行凌乱的-1乘法:

class ReversePriorityQueue(PriorityQueue):

def put(self, tup):
    newtup = tup[0] * -1, tup[1]
    PriorityQueue.put(self, newtup)

def get(self):
    tup = PriorityQueue.get(self)
    newtup = tup[0] * -1, tup[1]
    return newtup
这似乎适用于元组,至少:

Q = ReversePriorityQueue()

In [94]: Q.put((1,1))

In [95]: Q.get()
Out[95]: (1, 1)

In [96]: Q.put((1,1))

In [97]: Q.put((5,5))

In [98]: Q.put((9,9))

In [99]: Q.get()
Out[99]: (9, 9)

In [100]: Q.get()
Out[100]: (5, 5)

In [101]: Q.get()
Out[101]: (1, 1)

我相信您可以从这里概括代码,使其不只是使用元组。

您可以使用自定义类而不是元组。
然后,您可以在cmp中执行任何您喜欢的操作。

如果您希望避免在放入优先级队列时乘以-1。你可以这样做

创建一个包装类

class Wrapper:
    def __init__(self, value):
        self.value = value
    
    def __lt__(self, next):
        return self.value[0] > next.value[0]

请注意,我修改了
\uu lt\uuu
函数,我使用了
而不是
,我阅读了规范,但认为可能缺少了另一种特殊方法或其他什么。没关系,我想我可以乘以-1,但那意味着每次我想从队列后面拿东西的时候,都会把所有东西都推到一个堆栈上,不是吗?我想这是非常低效的,特别是对于非常大的输入大小。。
class Wrapper:
    def __init__(self, value):
        self.value = value
    
    def __lt__(self, next):
        return self.value[0] > next.value[0]
from queue import PriorityQueue
pq = PriorityQueue()
pq.put(Wrapper((priority, 'extra data')))
t = pq.get().value