word frequency
file processing
text analysis
efficiency
data manipulation

Given a file, find the ten most frequently occurring words as efficiently as possible

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Finding the ten most frequent words in a file is mostly a streaming and counting problem, not a sorting problem. The efficient solution reads the file incrementally, normalizes tokens consistently, counts with a hash map, and then extracts only the top ten counts rather than sorting everything unnecessarily.

Stream the File Instead of Loading It All

For large files, do not read the whole file into memory just to count words. Process line by line:

python
1from collections import Counter
2import re
3
4word_re = re.compile(r"[A-Za-z0-9']+")
5
6counter = Counter()
7
8with open("book.txt", "r", encoding="utf-8") as handle:
9    for line in handle:
10        words = word_re.findall(line.lower())
11        counter.update(words)

This keeps memory usage reasonable because the file content is streamed while only the counts are retained.

Extract the Top Ten Efficiently

Once counting is done, Counter.most_common(10) is the simplest and usually the best answer:

python
1top_ten = counter.most_common(10)
2
3for word, count in top_ten:
4    print(word, count)

For most practical workloads, this is both fast and readable. Under the hood, the important optimization is that you are not sorting the entire file content, only the map of unique words.

A Full Runnable Example

Putting the pieces together:

python
1from collections import Counter
2import re
3
4
5def top_words(path: str, limit: int = 10):
6    word_re = re.compile(r"[A-Za-z0-9']+")
7    counter = Counter()
8
9    with open(path, "r", encoding="utf-8") as handle:
10        for line in handle:
11            counter.update(word_re.findall(line.lower()))
12
13    return counter.most_common(limit)
14
15
16for word, count in top_words("book.txt"):
17    print(f"{word}: {count}")

This is already efficient enough for a large range of real files and easy to adapt when you need additional filtering rules.

Tokenization Rules Matter

The code above treats contractions such as don't as one word because the regex allows apostrophes. That may or may not match your business rule. Decide early on:

  • whether punctuation should be removed
  • whether case should be normalized
  • whether numbers count as words
  • whether stop words should be excluded

Efficiency is meaningless if the tokenization rule is wrong for the analysis you need.

When a Heap Is Useful

If you are not using Counter.most_common(), a heap is a good alternative:

python
1import heapq
2
3top_ten = heapq.nlargest(10, counter.items(), key=lambda item: item[1])
4print(top_ten)

This avoids fully sorting all unique words when you only need a small top slice. That matters more when the vocabulary is huge.

Very Large Inputs and Limits

For a single ordinary text file, the bottleneck is usually I/O plus counting. For truly massive datasets, additional strategies may matter:

  • process multiple files in chunks
  • merge partial counts later
  • use external tools or distributed processing

The main memory cost is the dictionary of unique words. If the text contains millions of distinct tokens, that can still become large even though the file itself is streamed. For that kind of workload, the algorithm remains conceptually the same, but the execution model changes from one in-process dictionary to staged aggregation across chunks or workers.

Common Pitfalls

  • Reading the entire file into memory before counting.
  • Sorting every counted word when only the top ten results are needed.
  • Using inconsistent tokenization rules and then distrusting the final counts.
  • Ignoring case normalization and treating Word and word as different tokens accidentally.
  • Optimizing prematurely with exotic approaches before measuring whether a plain streaming Counter solution is already sufficient.

Summary

  • Read the file line by line to keep memory use under control.
  • Normalize words consistently before counting them.
  • Use Counter.update() to accumulate frequencies efficiently.
  • Use most_common(10) or a heap to extract only the top results.
  • Focus on correct tokenization first, then optimize the counting path if the dataset truly demands it.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design