How to Find the n Smallest Items in a Large List with heapq in Python

This code demonstrates how to efficiently extract the n smallest items from a large list using Python's heapq module and a manual max-heap approach.

Medium Python 3.9+ Aug 9, 2026 Algorithms & data structures 13 views 0 copies

Python code

25 lines
Python 3.9+
import heapq

def n_smallest_iterable(data, n):
    """Return the n smallest items without loading the whole list."""
    if n <= 0:
        return []
    return heapq.nsmallest(n, data)

def n_smallest_manual(data, n):
    """Return the n smallest using a heap, O(n log k) time."""
    if n <= 0:
        return []
    heap = []
    for item in data:
        if len(heap) < n:
            heapq.heappush(heap, -item)  # max-heap via negation
        elif item < -heap[0]:
            heapq.heapreplace(heap, -item)
    return sorted(-x for x in heap)

if __name__ == "__main__":
    large_list = [42, 7, 99, 1, 5, 17, 3, 20, 8, 2]
    k = 3
    print("nsmallest:", n_smallest_iterable(large_list, k))
    print("manual   :", n_smallest_manual(large_list, k))

Output

stdout
nsmallest: [1, 2, 3]
manual   : [1, 2, 3]

How it works

The heapq.nsmallest function is optimized for finding a small number of smallest items from a large iterable. It uses a heap of size n internally, which gives O(n log k) time complexity. The manual implementation replicates this by maintaining a max-heap of size k using negation: we push negative values so the largest positive value becomes the smallest in the heap. As we iterate, if a new item is smaller than the current maximum in the heap, we replace it, ensuring the heap always contains the k smallest seen so far. Finally, we negate and sort the heap items to return them in ascending order.

Common mistakes

  • Forgetting to handle n <= 0, which should return an empty list rather than raising an error.
  • Using positive values in a max-heap without negation, causing incorrect results.
  • Modifying the original data order or assuming the input is sorted.
  • Calling `sorted` on the heap without negating back the stored values.

Variations

  1. Use `heapq.nlargest` for the n largest items, symmetrical to this pattern.
  2. For data that fits in memory, simply sort and slice: `sorted(data)[:n]`.

Real-world use cases

  • Finding the top 10 cheapest products from a large e-commerce catalog without sorting everything.
  • Selecting the n smallest response times from millions of API request logs for performance analysis.
  • Extracting the n lowest-priority tasks from a long task queue in a scheduling system.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Algorithms & data structures

Related tutorials and quizzes for this topic.