I want to get the next item in queue but I don't want to dequeue it. Is it possible in Python's queue.PriorityQueue
? From the docs, I don't see how can it be done
When you get item form the queue as per theory it will remove from the queue. You have to write your own function which will give you last element of PriorityQueue. You can create a peek function by inherit the priorityqueue.
self.queue
in the example. Also u can check the _get
method of PriorityQueue so if you want to change that functionality then also override that function. –
Ostrich If a is a PriorityQueue object, You can use a.queue[0]
to get the next item:
from queue import PriorityQueue
a = PriorityQueue()
a.put((10, "a"))
a.put((4, "b"))
a.put((3,"c"))
print(a.queue[0])
print(a.queue)
print(a.get())
print(a.queue)
print(a.get())
print(a.queue)
output is :
(3, 'c')
[(3, 'c'), (10, 'a'), (4, 'b')]
(3, 'c')
[(4, 'b'), (10, 'a')]
(4, 'b')
[(10, 'a')]
but be careful about multi thread access.
q.queue[0]
returns the highest priority item in the queue, q.queue[1]
does not necessarily return the 2nd highest priority item –
Gunshy q.queue[1]
or q.queue[2]
. That is because according to the theory of Priority Queues, the parent (q.queue[0]
in this case) must have a higher priority that either of its two children (q.queue[1]
and q.queue[2]
), but the specific order of these two children is not important. This means that the whole q.queue is not absolutely sorted, only "heap" sorted (i.e every level has a higher priority than the level below it) –
Buonarroti a.queue[0]
first construct the array and then return the first element? so O(n)? –
Snaggy a.queue
as its storage. The list is how the queue is stored in memory, in plain. As long as the queue is constructed, the list must there. By accessing the list directly you just circumvent the whole logic of the queue and go straight to its storage. –
Chrystel a.queue[0]
is, thus, constant time. –
Chrystel If you want next element in the PriorityQueue, in the order of the insertion of the elements, use:
for i in range(len(queue.queue)):
print queue.queue[i]
this will not pop anything out.
If you want it in the priority order, use:
for i in range(len(queue.queue)):
temp = queue.get()
queue.put(temp)
print temp
If you are using a tuple, instead of a single variable, replace temp by:
((temp1,temp2))
Assuming your items stored in the PriorityQueue is a tuple (priority, value),
def peek(pq):
return pq.queue[0][1]
Indexing the first element of the queue should work. If you're using the heapq
library, the document mentions:
The interesting property of a heap is that its smallest element is always the root,
heap[0]
.
When you get item form the queue as per theory it will remove from the queue. You have to write your own function which will give you last element of PriorityQueue. You can create a peek function by inherit the priorityqueue.
self.queue
in the example. Also u can check the _get
method of PriorityQueue so if you want to change that functionality then also override that function. –
Ostrich If q
is the PeriorityQueue, then you can use:
for i in range(q.qsize()):
print(q.queue[i])
TL;DR -- If you are are using the top item multiple times in a multithreaded environment, you should assign the item to a variable.
The above answers show how to access the elements of a PriorityQueue, however there is some danger when accessing objects from the inner queue in a multithreaded manner (as mentioned at the end of HYRY's answer).
While holding onto the queue
object would be even less threadsafe, because that queue
object is "live" (see this answer), you can still run into issues when accessing the objects on the queue if you expect the object ordering to be static.
Here's an example:
from queue import PriorityQueue
import threading
import time
pq = PriorityQueue()
def queue_manip():
i = 0
while True:
pq.put((i, i))
i -= 1
time.sleep(.1)
t1 = threading.Thread(target=queue_manip)
t1.start()
while True:
print('FirstAccess: ', pq.queue[0])
time.sleep(.2) # other processing
print('SecondAccess: ', pq.queue[0])
time.sleep(.2) # other processing
print()
which will print something like the below:
FirstAccess: (0, 0)
SecondAccess: (-1, -1)
FirstAccess: (-3, -3)
SecondAccess: (-5, -5)
FirstAccess: (-7, -7)
SecondAccess: (-9, -9)
For this reason, if you want to use an object from the top of a PriorityQueue
, you should assign that object to a name:
from queue import PriorityQueue
import threading
import time
pq = PriorityQueue()
def queue_manip():
i = 0
while True:
pq.put((i, i))
i -= 1
time.sleep(.1)
t1 = threading.Thread(target=queue_manip)
t1.start()
while True:
priority, item = pq.queue[0]
print('FirstUse: ', item)
time.sleep(.2) # other processing
print('SecondUse: ', item)
time.sleep(.2) # other processing
print()
which will give you:
FirstUse: 0
SecondUse: 0
FirstUse: -3
SecondUse: -3
FirstUse: -7
SecondUse: -7
© 2022 - 2024 — McMap. All rights reserved.