In the Python docs,
The lowest valued entries are retrieved first (the lowest valued entry is the one returned by
sorted(list(entries))[0]
). A typical pattern for entries is a tuple in the form:(priority_number, data)
.
It appears the queue will be sorted by priority then data, which may not be always correct. Suppose data "item 2", is enqueued before "item 1", item 1 will still go first. In another docs page, heapq, it suggests the use of a counter. So I will store my data like entry = [priority, count, task]
. Isn't there something like
PriorityQueue.put(item, priority)
Then I won't need to implement the ordering myself?
1. Adding Elements: In order to add an element in a priority queue, we can use the add() method. The insertion order is not retained in the PriorityQueue. The elements are stored based on the priority order which is ascending by default.
To implement a priority queue in Python, we have to declare an empty Python list into which elements are inserted using the append() method of list class. The list is then sorted in ascending order. The While loop is used to retrieve the elements using the pop() method.
In computer science, a priority queue is an abstract data-type similar to a regular queue or stack data structure in which each element additionally has a priority associated with it. In a priority queue, an element with high priority is served before an element with low priority.
Just use the second item of the tuple as a secondary priority if a alphanumeric sort on your string data isn't appropriate. A date/time priority would give you a priority queue that falls back to a FIFIO queue when you have multiple items with the same priority. Here's some example code with just a secondary numeric priority. Using a datetime value in the second position is a pretty trivial change, but feel free to poke me in comments if you're not able to get it working.
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
Here's what it looks like if you use a timestamp to fake FIFO as a secondary priority using a date. I say fake because it's only approximately FIFO as entries that are added very close in time to one another may not come out exactly FIFO. I added a short sleep so this simple example works out in a reasonable way. Hopefully this helps as another example of how you might get the ordering you're after.
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)
As far as I know, what you're looking for isn't available out of the box. Anyway, note that it wouldn't be hard to implement:
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()
Example output:
item2 item1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With