[英]How do I reverse the order of PriorityQueue in python?
I have created a simple priority queue in python that orders items by their value:我在 python 中创建了一个简单的优先级队列,它按项目的值对项目进行排序:
import Queue
q = Queue.PriorityQueue()
for it in items:
q.put((it.value, it))
but when i print the queue using:但是当我使用以下方法打印队列时:
while not q.empty()
print q.get()
it will always print the lowest value first.它将始终首先打印最低值。 is there a way of getting the last item in a queue without changing the last two lines in the top bit of code to:
有没有办法在不将代码顶部的最后两行更改为:
for it in items:
q.put((-1*it.value, it))
because that seems a bit messy and creates problems if i want to use that information for something else (i would have to multiply it by -1 again)因为如果我想将该信息用于其他用途,这似乎有点混乱并且会产生问题(我必须再次将其乘以 -1)
You could just make your own class that inherits from PriorityQueue and does the messy -1 multiplication under the hood for you:您可以创建自己的类,该类继承自 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
This appears to work with tuples, at least:这似乎适用于元组,至少:
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)
I'm sure you could generalize the code to work with more than just tuples from here.我相信您可以将代码概括为不仅可以使用这里的元组。
You can make the transformation transparent.您可以使转换透明。
What you want is to have a new q.get
and a new q.put
that transparently modifies data in and out of queue to reverse order:你想要的是有一个新的
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()
If this is to be made to a more robust code I strongly recommend using a class and not just re-bind the methods.如果这是为了更健壮的代码,我强烈建议使用类,而不仅仅是重新绑定方法。
You can use a customized Class instead of a tuple.您可以使用自定义类而不是元组。 Then you can do whatever you like in the cmp.
然后你可以在 cmp 中做任何你喜欢做的事情。
If you'd like to avoid multiplying by -1 when putting to the priority queue.如果您想在放入优先级队列时避免乘以 -1。 You can do something like this.
你可以做这样的事情。
Make a wrapper class制作一个包装类
class Wrapper:
def __init__(self, value):
self.value = value
def __lt__(self, next):
return self.value[0] > next.value[0]
Notice that I've modified the __lt__
function, I've used >
instead of <
deliberately.请注意,我修改了
__lt__
函数,我特意使用了>
而不是<
。
Now for putting an element to the Priority Queue do现在将元素放入优先级队列
from queue import PriorityQueue
pq = PriorityQueue()
pq.put(Wrapper((priority, 'extra data')))
Now while getting the element make sure to use the value
attribute instead现在在获取元素时确保使用
value
属性代替
t = pq.get().value
By definition you can only retrieve items from the front of a queue.根据定义,您只能从队列前端检索项目。 To reverse the order, you could push everything onto a stack, and then pop items off the stack.
要颠倒顺序,您可以将所有内容推入堆栈,然后从堆栈中弹出项目。 Since a stack both adds and retrieves items from its back, this has the same effect as reversing the queue.
由于堆栈从其背面添加和检索项目,因此这与反转队列具有相同的效果。
In the case of Queue.PriorityQueue
在
Queue.PriorityQueue
的情况下
The lowest valued entries are retrieved first (the lowest valued entry is the one returned by sorted(list(entries))[0]).
首先检索最低值的条目(最低值的条目是 sorted(list(entries))[0] 返回的条目)。
So can you try queue.LifoQueue
.It is of LIFO
mechanism.所以你可以试试
queue.LifoQueue
它是LIFO
机制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.