PYTHON
Implement a Priority Queue with `heapq`
Learn to build a min-priority queue in Python using the `heapq` module, essential for algorithms like Dijkstra's or for managing tasks based on priority.
import heapq
class PriorityQueue:
def __init__(self):
# A list to store items, where the first element is the priority.
# heapq maintains the min-heap property: item[0] <= item[0] of its children.
self._queue = []
# A counter to ensure consistent ordering for items with the same priority
# and to break ties (lower index means older item).
self._index = 0
def push(self, item, priority):
# Tuples are compared lexicographically, so (priority, index, item) works.
# The smaller priority comes first. If priorities are equal, the smaller index comes first.
heapq.heappush(self._queue, (priority, self._index, item))
self._index += 1
def pop(self):
# Removes and returns the smallest item (highest priority)
if not self._queue:
raise IndexError("pop from an empty priority queue")
# We only care about the actual item, not priority or index
return heapq.heappop(self._queue)[-1]
def is_empty(self):
return not self._queue
def size(self):
return len(self._queue)
# Usage
pq = PriorityQueue()
pq.push('task A', 3)
pq.push('task B', 1)
pq.push('task C', 2)
pq.push('task D', 1) # Same priority as task B, but inserted later
print(f"Priority Queue size: {pq.size()}")
print(f"Popped item: {pq.pop()}") # Should be 'task B' (priority 1, earlier index)
print(f"Popped item: {pq.pop()}") # Should be 'task D' (priority 1, later index)
print(f"Popped item: {pq.pop()}") # Should be 'task C' (priority 2)
print(f"Popped item: {pq.pop()}") # Should be 'task A' (priority 3)
print(f"Is Priority Queue empty? {pq.is_empty()}")
try:
pq.pop()
except IndexError as e:
print(f"Error: {e}")
How it works: The `heapq` module in Python provides an implementation of the min-heap priority queue algorithm. This snippet demonstrates how to wrap `heapq` functions to create a user-friendly `PriorityQueue` class. Items are pushed with an associated priority, and `heappop` always retrieves the item with the smallest priority. By including an `_index` in the tuple stored in the heap, we ensure stable sorting for items with identical priorities, making it reliable for managing tasks or elements in order of importance.