heapq
What it is
Section titled βWhat it isβheapq is a standard-library module implementing a binary min-heap directly on top of a regular Python list β thereβs no separate heap class, just functions (heappush, heappop, etc.) that maintain the heap-ordering invariant on a list you pass in. The smallest element is always at index 0, and heappop removes/returns it in O(log n).
Before this feature
Section titled βBefore this featureβRepeatedly finding and removing the smallest item from a plain list means re-sorting or re-scanning every time:
tasks = [(5, "low priority"), (1, "urgent"), (3, "medium")]
# To get the smallest each time without heapq:tasks.sort() # O(n log n) every time something changessmallest = tasks.pop(0) # O(n) β pop(0) has to shift every remaining elementAfter this feature
Section titled βAfter this featureβimport heapq
tasks = [(5, "low priority"), (1, "urgent"), (3, "medium")]heapq.heapify(tasks) # O(n) -- rearrange in place into heap order
heapq.heappush(tasks, (2, "high priority"))print(heapq.heappop(tasks)) # (1, 'urgent') -- always the smallest, O(log n)print(heapq.heappop(tasks)) # (2, 'high priority')# Common use: "top N" without sorting the whole listscores = [45, 89, 12, 67, 93, 21, 78]print(heapq.nlargest(3, scores)) # [93, 89, 78]print(heapq.nsmallest(3, scores)) # [12, 21, 45]Why this is better
Section titled βWhy this is betterβ- Fast repeated min-extraction:
heappopis O(log n), versus O(n log n) to re-sort or O(n) to scan for the minimum every time β matters when youβre repeatedly pulling the smallest item as the collection changes (a priority queue is the classic use case). - In-place on a plain list: no special data structure to import and manage separately β
heapqoperates directly on alistyou already have. nlargest/nsmallestavoid a full sort: getting the top 3 out of a million items doesnβt require sorting all million.
Key notes / edge cases
Section titled βKey notes / edge casesβheapqis a min-heap only β the smallest item is always first. For a max-heap, negate the values on the way in and out (heapq.heappush(h, -value)), or store(-priority, item)tuples as shown above with priorities.- The heap only guarantees
heap[0]is the smallest β the rest of the list is not fully sorted, just heap-ordered (each parent β€ its children). Donβt assumeheap[1]is the second-smallest. - Ties between equal first elements in tuples fall through to comparing the second element β
(1, "urgent")vs(1, "also urgent")would compare the strings, which can raise aTypeErrorif the second elements arenβt comparable (a common gotcha when heap items are(priority, non-comparable-object)). heapify()rearranges an existing list in O(n); pushing items one at a time with repeatedheappushcosts O(n log n) β preferheapify()when you already have all the initial items.
Quick practice
Section titled βQuick practiceβ-
Whatβs the time complexity of
heapq.heappop()?Answer
O(log n). -
Does
heapqimplement a min-heap or a max-heap by default?Answer
A min-heap β `heap[0]` is always the smallest element. A max-heap requires negating values yourself. -
After calling
heapq.heapify(some_list), is the entire list fully sorted?Answer
No β only the heap-order invariant is guaranteed (each parent β€ its children, so index 0 is the smallest); the rest of the list is not in sorted order.