I think the key idea you're missing to implement your PriorityQueue class is that each PriorityQueue instance should have a Heap instance as an attribute. Set it up in __init__:

class PriorityQueue(object):
    def __init__(self)
        self.heap = Heap()

When a user makes a call to a PriorityQueue method, that method will mostly just make a call to a method of self.heap, with just a little extra work modifying the arguments or the return value. The items to insert into the heap should probably be (priority, value) tuples, since they will compare appropriately (higher priority items comparing higher).

Note that if you compare code written for heapq with your Heap, you'll need to modify the logic for the indexes and priorities, since heapq implements a zero-indexed min-heap, and your code implements a one-indexed max-heap.

Answer from Blckknght on Stack Overflow
Top answer
1 of 3
128

Queue.PriorityQueue is a thread-safe class, while the heapq module makes no thread-safety guarantees. From the Queue module documentation:

The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics. It depends on the availability of thread support in Python; see the threading module.

The heapq module offers no locking, and operates on standard list objects, which are not meant to be thread-safe.

In fact, the PriorityQueue implementation uses heapq under the hood to do all prioritisation work, with the base Queue class providing the locking to make this thread-safe. See the source code for details.

This makes the heapq module faster; there is no locking overhead. In addition, you are free to use the various heapq functions in different, novel ways, the PriorityQueue only offers the straight-up queueing functionality.

2 of 3
30

queue.PriorityQueue is a partial wrapper around the heapq class.

In other words, a queue.PriorityQueue is actually a heapq, placed in the queue module with a couple of renamed methods to make the heapq easier to use, much like a regular queue.

In heapq, you use use the method heappush() to add a new item and the method heappop() to remove one. That is not very queue-like, so queue.PriorityQueue let you use the usual queue methods such as put and get to do the same thing.

There are some features of heapq that are not carried over into queue.PriorityQueue, such as heappushpop() and heapreplace(), but you are less likely to use those. If you need them (and I do in my current project), perhaps you should use heapq rather than queue.PriorityQueue.

Also, since heapq is specialized for its purpose, it is not thread safe (as noted in another answer here.)

🌐
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.

Top answer
1 of 2
2

It depends on what your definition of priority is, but you're going to have to iterate over your collection yourself, looking for the place to insert the next node:

node = self.head
while node.next and node.next.priority > priority:
    node = node.next

if node.next is None:
    node.next = qNode(value=value, next=None, priority=priority)
    self.foot = node.next
else:
    new_node = qNode(value=value, next=node.next, priority=priority)
    node.next = new_node

You'll have to add a priority to your qNode, of course, and you may have to adjust exactly where you're going to insert, but this should get you most of the way there.

2 of 2
0

Here is the implementation of priority queue in python using linked list:-

# Python code to implement Priority Queue using Linked List
# Node class 
class Node:
    def __init__(self, item, priority):
        self.item = item
        self.next = None
        self.priority = priority

class PriorityQueue:
    def __init__(self):
        self.front = self.rear = None

    # Returns a boolean value indicating whether the queue is empty
    def isEmpty(self):
        return self.front == None

    # Adds the given item to the queue by inserting it in the proper 
    # position based on the given priority. The new node is appended to 
    # the end of the linked list
    def enqueue(self, item, priority):
        newNode = Node(item, priority)
        if not self.rear:
            self.front = self.rear = newNode
            return
        if self.front.priority < newNode.priority:
            newNode.next = self.front
            self.front = newNode
            return
        previous = None
        current = self.front
        while(current and newNode.priority < current.priority):
            previous = current
            current = current.next

        if current:
            previous.next = newNode
            newNode.next = current
        else:
            self.rear.next = newNode
            self.rear = newNode

    # Removes and returns the next item from the queue, which is the 
    # item with the highest priority. If two or more items have the 
    # same priority, those items are removed in FIFO order. An item 
    # cannot be dequeued from an empty queue. 
    def dequeue(self):
        if self.isEmpty():
            print('Queue is empty')
            return
        temp = self.front
        self.front = self.front.next
        if self.front == None:
            self.rear = None
        return temp.item
🌐
Reddit
reddit.com › r/python › heap/priority queue that supports removing arbitrary items and frequency tracking
r/Python on Reddit: Heap/Priority Queue that supports removing arbitrary items and frequency tracking
October 23, 2025 -

I created a Python heap implementation that supports:

  • Removing any item (not just the root via pop)

  • Tracking the frequency of items so that duplicates are handled efficiently

Source: https://github.com/Ite-O/python-indexed-heap
PyPI: https://pypi.org/project/indexedheap/

What My Project Does

indexedheap is a Python package that provides standard heap operations, insert (push), pop, and peek, along with additional features:

  • Remove any arbitrary item efficiently.

  • Track frequencies of items to handle duplicates.

  • Insert or remove multiple occurrences in a single operation.

  • Iterate over heap contents in sorted order without modifying the heap.

It is designed for scenarios requiring dynamic priority queues, where an item’s priority may change over time Common in task schedulers, caching systems or pathfinding algorithms.

Target Audience

  • Developers needing dynamic priority queues where priorities can increase or decrease.

  • Users who want duplicate-aware heaps for frequency tracking.

  • Engineers implementing task schedulers, caches, simulations or pathfinding algorithms in Python.

Comparison

Python’s built-in heapq vs indexedheap

Operation Description heapq indexedheap
heappush(heap, item) / insert(value) Add an item/value to the heap O(log N) O(log N) / (O(1) if item already exists and count is incremented)
heappop(heap) / pop() Remove and return the root item/value O(log N) O(log N)
heap[0] / peek() Return root item/value without removing it ✅ Manual (heap[0]) O(1)
remove(value) Remove any arbitrary value ❌ Not supported O(log(N)) for last occurence in heap, O(1) if only decrementing frequency
heappushpop(heap, item) Push then pop in a single operation O(log N) ❌ Not directly supported (use insert() + pop())
heapreplace(heap, item) Pop then push in a single operation O(log N) ❌ Not directly supported (use pop() + insert())
count(value) Get frequency of a specific value ❌ Not supported O(1)
item in heap / value in heap Membership check ⚠️ O(N) (linear scan) O(1)
len(heap) Number of elements O(1) O(1)
to_sorted_list() Return sorted elements without modifying heap ✅ Requires creating a sorted copy of the heap O(N log N) O(N log N)
iter(heap) Iterate in sorted order ✅ Requires creating a sorted copy of the heap and iterating over the copy O(N log N)) O(N log N)
heapify(list) / MinHeap(list), MaxHeap(list) Convert list to valid heap O(N) O(N)
heap1 == heap2 Structural equality check O(N) O(N)
Frequency tracking Track frequency of items rather than store duplicates ❌ Not supported ✅ Yes
Multi-inserts/removals Insert/ remove multiples of an item in a single operation ❌ Not supported ✅ Yes (see insert/ remove rows for time complexity)

Installation

pip install indexedheap

Feedback

If there is demand, I am considering adding support for heappushpop and heapreplace operations, similar to those in Python's heapq module.

Open to any feedback!

Updates

  • Updated terminology in the comparison table to show both "value" and "item" in some rows. Since the terminology used in my package for the inserted object is "value", whereas the terminology used in heapq is "item".

🌐
Towards Data Science
towardsdatascience.com › home › latest › priority queues in python
Priority Queues in Python | Towards Data Science
January 26, 2025 - In this post, we will discuss the implementation of a priority queue in python using a heap data structure. Let’s get started! It is worth familiarizing ourselves with the python ‘heapq’ module before we build our ‘PriorityQueue’ class.
🌐
Built In
builtin.com › data-science › priority-queues-in-python
Introduction to Priority Queues in Python | Built In
It can be implemented using lists, the heapq module for efficiency, or the thread-safe PriorityQueue class for concurrent applications. A queue in Python is a data structure that follows a first-in-first-out (FIFO) order, in which items are taken out or accessed on a first-come-first-served basis.
🌐
Hostman
hostman.com › tutorials › implementing a priority queue in python
Implementing a Priority Queue in Python: A Comprehensive Guide
December 29, 2025 - Updating an element's priority involves removing the element and adding it again with the new priority. This can be inefficient, but it's a necessary step since heapq does not support direct priority updates.
Price   $
Address   1999 Harrison St 1800 9079, 94612, Oakland
Find elsewhere
Top answer
1 of 3
33

There is no such thing as a "most efficient priority queue implementation" in any language.

A priority queue is all about trade-offs. See http://en.wikipedia.org/wiki/Priority_queue

You should choose one of these two, based on how you plan to use it:

  • O(log(N)) insertion time and O(1) (findMin+deleteMin)* time, or
  • O(1) insertion time and O(log(N)) (findMin+deleteMin)* time

(* sidenote: the findMin time of most queues is almost always O(1), so here I mostly mean the deleteMin time can either be O(1) quick if the insertion time is O(log(N)) slow, or the deleteMin time must be O(log(N)) slow if the insertion time is O(1) fast. One should note that both may also be unnecessarily slow like with binary-tree based priority queues.)

In the latter case, you can choose to implement a priority queue with a Fibonacci heap: http://en.wikipedia.org/wiki/Heap_(data_structure)#Comparison_of_theoretic_bounds_for_variants (as you can see, heapq which is basically a binary tree, must necessarily have O(log(N)) for both insertion and findMin+deleteMin)

If you are dealing with data with special properties (such as bounded data), then you can achieve O(1) insertion and O(1) findMin+deleteMin time. You can only do this with certain kinds of data because otherwise you could abuse your priority queue to violate the O(N log(N)) bound on sorting. vEB trees kind of fall under a similar category, since you have a maximum set size (O(log(log(M)) is not referring to the number of elements, but the maximum number of elements) and thus you cannot circumvent the theoretical O(N log(N)) general-purpose comparison-sorting bound.

To implement any queue in any language, all you need is to define the insert(value) and extractMin() -> value operations. This generally just involves a minimal wrapping of the underlying heap; see http://en.wikipedia.org/wiki/Fibonacci_heap to implement your own, or use an off-the-shelf library of a similar heap like a Pairing Heap (a Google search revealed http://svn.python.org/projects/sandbox/trunk/collections/pairing_heap.py )


If you only care about which of the two you referenced are more efficient (the heapq-based code from http://docs.python.org/library/heapq.html#priority-queue-implementation-notes which you included above, versus Queue.PriorityQueue), then:

There doesn't seem to be any easily-findable discussion on the web as to what Queue.PriorityQueue is actually doing; you would have to source dive into the code, which is linked to from the help documentation: http://hg.python.org/cpython/file/2.7/Lib/Queue.py

Copy   224     def _put(self, item, heappush=heapq.heappush):
   225         heappush(self.queue, item)
   226 
   227     def _get(self, heappop=heapq.heappop):
   228         return heappop(self.queue)

As we can see, Queue.PriorityQueue is also using heapq as an underlying mechanism. Therefore they are equally bad (asymptotically speaking). Queue.PriorityQueue may allow for parallel queries, so I would wager that it might have a very slightly constant-factor more of overhead. But because you know the underlying implementation (and asymptotic behavior) must be the same, the simplest way would simply be to run them on the same large dataset.

(Do note that Queue.PriorityQueue does not seem to have a way to remove entries, while heapq does. However this is a double-edged sword: Good priority queue implementations might possibly allow you to delete elements in O(1) or O(log(N)) time, but if you use the remove_task function you mention, and let those zombie tasks accumulate in your queue because you aren't extracting them off the min, then you will see asymptotic slowdown which you wouldn't otherwise see. Of course, you couldn't do this with Queue.PriorityQueue in the first place, so no comparison can be made here.)

2 of 3
29

The version in the Queue module is implemented using the heapq module, so they have equal efficiency for the underlying heap operations.

That said, the Queue version is slower because it adds locks, encapsulation, and a nice object oriented API.

The priority queue suggestions shown in the heapq docs are meant to show how to add additional capabilities to a priority queue (such as sort stability and the ability to change the priority of a previously enqueued task). If you don't need those capabilities, then the basic heappush and heappop functions will give you the fastest performance.

🌐
Python
docs.python.org › 3 › library › heapq.html
heapq — Heap queue algorithm
The remaining challenges revolve around finding a pending task and making changes to its priority or removing it entirely. Finding a task can be done with a dictionary pointing to an entry in the queue.
🌐
GeeksforGeeks
geeksforgeeks.org › python › heap-and-priority-queue-using-heapq-module-in-python
Heap and Priority Queue using heapq module in Python - GeeksforGeeks
July 23, 2025 - The programmer can decide whether the largest number is considered as the highest priority or the lowest number will be considered as the highest priority. If two elements have the same priority, then they appear in the order in which they appear in the queue. Heapq module is an implementation of heap queue algorithm (priority queue algorithm) in which the property of min-heap is preserved.
🌐
GeeksforGeeks
geeksforgeeks.org › python › difference-between-heapq-and-priorityqueue-in-python
Difference Between heapq and PriorityQueue in Python - GeeksforGeeks
July 23, 2025 - In this article, we are going to see the difference between heapq and PriorityQueue in Python. Python queue PriorityQueue is thread-safe, but heapq doesn't guarantee thread safety.
🌐
Medium
medium.com › @2019077_13406 › priority-queue-v-s-heapq-python-a4858c0191ac
Priority Queue V/s Heapq Python. Lately, I have been solving LeetCode… | by kartik chuphal | Medium
December 15, 2024 - Upon reviewing the implementation, I found that PriorityQueue is essentially a thread-safe wrapper for heapq, which justifies why it’s slower. And folks, I encourage you to try implementing a priority queue from scratch — I’m planning to do the same after publishing this article!
🌐
iO Flood
ioflood.com › blog › python-priority-queue-practical-guide-with-examples
Python Priority Queue Examples | Best Practices and Usage
July 8, 2024 - It lacks the thread safety of PriorityQueue, and it necessitates a solid understanding of the heap queue algorithm for effective use. However, for specific use cases, particularly those that require custom comparison functions or frequent priority updates, heapq can be a highly effective tool. While Python’s PriorityQueue class is efficient, its performance can degrade with large data sets, especially when many items share the same priority.
🌐
DigitalOcean
digitalocean.com › community › tutorials › priority-queue-python
How to Use a Priority Queue in Python | DigitalOcean
July 11, 2025 - For thread-safe applications, the queue.PriorityQueue class offers a synchronized wrapper around heapq ... This tutorial will show you how to use each approach with practical examples. ... Apply priority queues to real-world scenarios like process scheduling, task management, and resource allocation · Optimize your applications by leveraging priority queues for ordered data processing · Debug common issues when working with priority queues in Python
🌐
The Python Coding Stack
thepythoncodingstack.com › p › python-heapq-heap-priority-queue
If You Love Queuing, Will You Also Love Priority Queuing? • [Club]
December 15, 2025 - We’ll use the list just as the structure to hold the data, but we’ll rely on another tool for the fun stuff. It’s time to import the heapq module, which is part of the Python standard library: ... This module contains the tools to create and manage a heap queue, which is also known as a priority queue.
🌐
Programiz
programiz.com › dsa › priority-queue
Priority Queue Data Structure
A priority queue is a special type of queue in which each element is associated with a priority and is served according to its priority. In this tutorial, you will understand the priority queue and its implementations in Python, Java, C, and C++.
🌐
Studytonight
studytonight.com › code › python › ds › priority-queue-in-python.php
Priority Queue in Python | Studytonight
Priority Queue also known as heap queues keeps the minimum value at the top. In this tutorial we will learn how we can implement a priority queue in python without using the heapq module.
🌐
Real Python
realpython.com › python-heapq-module
The Python heapq Module: Using Heaps and Priority Queues – Real Python
July 18, 2022 - Get the Source Code: Click here to get the source code you’ll use to learn about the Python heapq module in this tutorial. Heaps are concrete data structures, whereas priority queues are abstract data structures.