dataclasses is just a convenience method to avoid having to create a lot of boilerplate code.

You don't actually have to create a class. A tuple with a unique counter value too:

from itertools import count

unique = count()

q.put((priority, next(unique), item))

so that ties between equal priority are broken by the integer that follows; because it is always unique the item value is never consulted.

You can also create a class using straight-up rich comparison methods, made simpler with @functools.total_ordering:

from functools import total_ordering

@total_ordering
class PrioritizedItem:
    def __init__(self, priority, item):
        self.priority = priority
        self.item = item

    def __eq__(self, other):
        if not isinstance(other, __class__):
            return NotImplemented
        return self.priority == other.priority

    def __lt__(self, other):
        if not isinstance(other, __class__):
            return NotImplemented
        return self.priority < other.priority
Answer from Martijn Pieters on Stack Overflow
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ queue.html
queue โ€” A synchronized queue class
February 23, 2026 - Queue objects (Queue, LifoQueue, or PriorityQueue) provide the public methods described below.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ priority-queue-using-queue-and-heapdict-module-in-python
Priority Queue using Queue and Heapdict module in Python - GeeksforGeeks
January 8, 2026 - queue.PriorityQueue is a constructor to create a priority queue, where items are stored in priority order (lower priority numbers are retrieved first).
Discussions

python - Using queue.PriorityQueue, not caring about comparisons - Stack Overflow
I'm trying to use queue.PriorityQueue in Python 3(.6). I would like to store objects with a given priority. But if two objects have the same priority, I don't mind PriorityQueue.get to return eit... More on stackoverflow.com
๐ŸŒ stackoverflow.com
python - How to iterate over a Priority Queue? - Stack Overflow
As my good friend T. Payne showed in one of his videos: ` try: import queue as Queue except: import Queue <\blink> And you're covered for both 2017-09-17T20:56:42.697Z+00:00 ... The PriorityQueue is implemented as binary heap, which is implemented using a list (array) in python. More on stackoverflow.com
๐ŸŒ stackoverflow.com
python - How to put items into priority queues? - Stack Overflow
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: ( More on stackoverflow.com
๐ŸŒ stackoverflow.com
Is there a better priority queue?
You don't have to give a priority queue a tuple of (priority, value), that's just the most common use case. If you wanted to base priority on 3 variables, you could give (a, b, c, value), where ties between a values are broken by the b values, etc. More on reddit.com
๐ŸŒ r/Python
5
6
November 21, 2017
๐ŸŒ
Oracle
docs.oracle.com โ€บ javase โ€บ 8 โ€บ docs โ€บ api โ€บ java โ€บ util โ€บ PriorityQueue.html
PriorityQueue (Java Platform SE 8 )
March 16, 2026 - Creates a PriorityQueue with the specified initial capacity that orders its elements according to the specified comparator. ... comparator - the comparator that will be used to order this priority queue.
๐ŸŒ
Built In
builtin.com โ€บ data-science โ€บ priority-queues-in-python
Introduction to Priority Queues in Python | Built In
Summary: A priority queue in Python allows elements to be processed based on assigned priority rather than arrival order. It can be implemented using lists, the heapq module for efficiency, or the thread-safe PriorityQueue class for concurrent ...
๐ŸŒ
Stackify
stackify.com โ€บ a-guide-to-python-priority-queue
A Guide to Python Priority Queue - Stackify
February 18, 2025 - The PriorityQueue class uses tuples to store items, with the first element representing the priority. Lower numbers indicate higher priority. Hereโ€™s how you can perform basic operations: from queue import PriorityQueue # Create a PriorityQueue pq = PriorityQueue() # Add items to the priority queue pq.put((2, "Task 2")) pq.put((1, "Task 1")) pq.put((3, "Task 3")) # Remove items based on priority while not pq.empty(): print(pq.get())
Find elsewhere
๐ŸŒ
DigitalOcean
digitalocean.com โ€บ community โ€บ tutorials โ€บ priority-queue-python
How to Use a Priority Queue in Python | DigitalOcean
July 11, 2025 - A priority queue stores (priority, item) pairs so the element with the highest priority (or lowest, for min-heap) is removed first. Python ships two ready-made solutions: heapq and queue.PriorityQueue.
Top answer
1 of 5
8

dataclasses is just a convenience method to avoid having to create a lot of boilerplate code.

You don't actually have to create a class. A tuple with a unique counter value too:

from itertools import count

unique = count()

q.put((priority, next(unique), item))

so that ties between equal priority are broken by the integer that follows; because it is always unique the item value is never consulted.

You can also create a class using straight-up rich comparison methods, made simpler with @functools.total_ordering:

from functools import total_ordering

@total_ordering
class PrioritizedItem:
    def __init__(self, priority, item):
        self.priority = priority
        self.item = item

    def __eq__(self, other):
        if not isinstance(other, __class__):
            return NotImplemented
        return self.priority == other.priority

    def __lt__(self, other):
        if not isinstance(other, __class__):
            return NotImplemented
        return self.priority < other.priority
2 of 5
2

See priority queue implementation notes - just before the section you quoted (regarding using dataclasses) it tells you how to do it whitout them:

... is to store entries as 3-element list including the priority, an entry count, and the task. The entry count serves as a tie-breaker so that two tasks with the same priority are returned in the order they were added. And since no two entry counts are the same, the tuple comparison will never attempt to directly compare two tasks.

So simply add your items as 3rd element in a tuple (Prio, Count, YourElem) when adding to your queue.

Contreived example:

from queue import PriorityQueue

class CompareError(ValueError): pass

class O:
    def __init__(self,n):
        self.n = n

    def __lq__(self):
        raise CompareError

    def __repr__(self): return str(self)
    def __str__(self): return self.n

def add(prioqueue,prio,item):
    """Adds the 'item' with 'prio' to the 'priorqueue' adding a unique value that
    is stored as member of this method 'add.n' which is incremented on each usage."""
    prioqueue.put( (prio, add.n, item))
    add.n += 1

# no len() on PrioQueue - we ensure our unique integer via method-param
# if you forget to declare this, you get an AttributeError
add.n = 0

h = PriorityQueue()

add(h, 7, O('release product'))
add(h, 1, O('write spec 3'))
add(h, 1, O('write spec 2'))
add(h, 1, O('write spec 1'))
add(h, 3, O('create tests'))

for _ in range(4):
    item = h.get()
    print(item)

Using h.put( (1, O('write spec 1')) ) leads to

TypeError: '<' not supported between instances of 'O' and 'int'`

Using def add(prioqueue,prio,item): pushes triplets as items wich have guaranteed distinct 2nd values so our O()-instances are never used as tie-breaker.

Output:

(1, 2, write spec 3)
(1, 3, write spec 2)
(1, 4, write spec 1)
(3, 5, create tests)

see MartijnPieters answer @here for a nicer unique 2nd element.

๐ŸŒ
Spark By {Examples}
sparkbyexamples.com โ€บ home โ€บ python โ€บ python queue.priorityqueue methods
Python queue.priorityqueue Methods - Spark By {Examples}
May 31, 2024 - We can implement the Priority queue using Python queue.priorityqueue methods. Priorityqueue is similar to Queue but it will remove items from it based on Priority. Fewer priority items will never be removed first.
Top answer
1 of 4
16

queue.PriorityQueue is actually implemented using a list, and the put/get methods use heapq.heappush/heapq.heappop to maintain the priority ordering inside that list. So, if you wanted to, you could just iterate over the internal list, which is contained in the queue attribute:

>>> from queue import PriorityQueue
>>> q = PriorityQueue()
>>> q.put((5, "a"))
>>> q.put((3, "b"))
>>> q.put((25, "c"))
>>> q.put((2, "d"))
>>> print(q.queue)
[(2, 'd'), (3, 'b'), (25, 'c'), (5, 'a')]
2 of 4
6

The PriorityQueue is implemented as binary heap, which is implemented using a list (array) in python. To iterate over the queue you need to know the rules about where children are stored in the list.

The rules being that all nodes have two children, unless they are the last node to have children in which case they may have one child instead. All nodes that appear after the last node to have children will have zero children (duh).

A node's children are stored in relation to the node's own position in the list. Where i is the index of the nodes in the list then it's children are stored at:

  • 2 * i + 1
  • 2 * i + 2

However, the only requirement of a heap is that all a node's children have a value greater than or equal to the node's value (or greater than depending on the implementation).

For instance, in the above linked wiki page about binrary heap's you'll find the following image. The first item in the queue is the root. Quite obvious. The second item is the larger of the root's children. However, the third item could either be the remaining node of the root node, or either of the children of the second node in the queue. That is, the third item in the queue (25) could have been in the same position as either 19 or 1.

Thus, to iterate over the queue you need to keep track of all the currently "viewable" nodes. For instance:

def iter_priority_queue(queue):

    if queue.empty():
        return

    q = queue.queue
    next_indices = [0]
    while next_indices:
        min_index = min(next_indices, key=q.__getitem__)
        yield q[min_index]
        next_indices.remove(mix_index)
        if 2 * min_index + 1 < len(q):
            next_indices.append(2 * min_index + 1)
        if 2 * min_index + 2 < len(q):
            next_indices.append(2 * min_index + 2)

The method can be monkey patched onto queue.PriorityQueue if you're feeling lazy, but I would encourage you to implement your own priority queue class using the heapq module as the PriorityQueue comes with a lot of excess functionality (mainly it is thread safe which almost certainly don't need). It should be noted that the above method is not thread safe. If another thread modifies the queue whilst it is being iterated over then the above method will start yielding the wrong numbers and if you're lucky it may produce an exception.

๐ŸŒ
Wikipedia
en.wikipedia.org โ€บ wiki โ€บ Priority_queue
Priority queue - Wikipedia
November 10, 2025 - Priority queue serves highest priority items first. Priority values have to be instances of an ordered data type, and higher priority can be given either to the lesser or to the greater values with respect to the given order relation. For example, in Java standard library, PriorityQueue's the ...
Top answer
1 of 3
37

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.

Code

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)

Output

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

Edit

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)
2 of 3
32

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
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ dsa โ€บ priority-queue-set-1-introduction
Introduction to Priority Queue - GeeksforGeeks
October 18, 2025 - #include <iostream> #include <queue> #include <vector> using namespace std; int main() { // Create a max priority queue priority_queue<int> pq; // Insert elements into the priority queue pq.push(10); pq.push(30); cout << "Priority Queue elements (max-heap):\n"; // Access elements and pop them one by one while (!pq.empty()) { // Access the top (highest priority element) cout << "Top element: " << pq.top() << endl; // Remove the top element pq.pop(); // Print remaining size cout << "Remaining size: " << pq.size() << "\n\n"; } // Check if empty if (pq.empty()) { cout << "Priority Queue is now emp
๐ŸŒ
cppreference.com
en.cppreference.com โ€บ cpp โ€บ container โ€บ priority_queue
std::priority_queue - cppreference.com
April 26, 2025 - The priority queue is a container adaptor that provides constant time lookup of the largest (by default) element, at the expense of logarithmic insertion and extraction.
๐ŸŒ
iO Flood
ioflood.com โ€บ blog โ€บ python-priority-queue-practical-guide-with-examples
Python Priority Queue Module | Best Practices and Usage
July 8, 2024 - However, in a Priority Queue, this order is determined by the priority of the elements. So, an element that enters the queue later could leave earlier if its priority is higher. Python offers a built-in PriorityQueue class in the queue module.
๐ŸŒ
Oracle
docs.oracle.com โ€บ en โ€บ java โ€บ javase โ€บ 11 โ€บ docs โ€บ api โ€บ java.base โ€บ java โ€บ util โ€บ PriorityQueue.html
PriorityQueue (Java SE 11 & JDK 11 )
January 20, 2026 - Creates a PriorityQueue with the specified initial capacity that orders its elements according to the specified comparator. ... comparator - the comparator that will be used to order this priority queue.
๐ŸŒ
Reddit
reddit.com โ€บ r/python โ€บ is there a better priority queue?
r/Python on Reddit: Is there a better priority queue?
November 21, 2017 -

I know python has heapq and queue.priorityqueue but honestly, both of them are really cumbersome compared to Java's priorityqueue. I find it tedious to have to insert a tuple, with the first element in the tuple defining the priority. Also, it makes it hard to write more complex comparisons. Is there a way we can pass in a comparator to the Priorityqueue? I know it's possible to define classes with their own comparator method, but again, this is really tedious and I'm looking for something as close as possible to Java's PQ.

๐ŸŒ
Real Python
realpython.com โ€บ queue-in-python
Python Stacks, Queues, and Priority Queues in Practice โ€“ Real Python
December 1, 2023 - # queues.py from collections import deque from heapq import heappop, heappush # ... class PriorityQueue: def __init__(self): self._elements = [] def enqueue_with_priority(self, priority, value): heappush(self._elements, (priority, value)) def dequeue(self): return heappop(self._elements)
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ heapq.html
heapq โ€” Heap queue algorithm
Source code: Lib/heapq.py This module provides an implementation of the heap queue algorithm, also known as the priority queue algorithm. Min-heaps are binary trees for which every parent node has ...