File Handling
Programming
Read Specific Lines
Line Number Access
Code Tutorial

How to read specific lines from a file by line number?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Reading specific lines from a file is a common need in scripts, log processors, and simple data tools. The right technique depends on whether you need one line or many, whether the file is large, and whether the requested line numbers are sorted.

The Simple And Reliable Approach

For ordinary text files, iterate through the file with enumerate and collect the lines you care about.

python
1def read_lines(path: str, line_numbers: set[int]) -> dict[int, str]:
2    result = {}
3    with open(path, "r", encoding="utf-8") as handle:
4        for current_number, line in enumerate(handle, start=1):
5            if current_number in line_numbers:
6                result[current_number] = line.rstrip("\n")
7    return result
8
9
10print(read_lines("example.txt", {2, 5, 7}))

This is easy to understand and works well for a moderate number of line requests.

Why This Is Usually Good Enough

Text files do not naturally support constant-time random access by line number, because line lengths vary. To reach line 5000, a program usually has to scan the earlier lines unless it already built an index.

That is why a straightforward sequential scan is often the correct baseline instead of a sign that the code is naive.

Stop Early If The Requests Are Sorted

If the requested line numbers are known in ascending order, you can stop reading once you pass the largest requested line.

python
1def read_sorted_lines(path: str, requested: list[int]) -> dict[int, str]:
2    wanted = set(requested)
3    last_needed = max(requested)
4    result = {}
5
6    with open(path, "r", encoding="utf-8") as handle:
7        for current_number, line in enumerate(handle, start=1):
8            if current_number in wanted:
9                result[current_number] = line.rstrip("\n")
10            if current_number >= last_needed:
11                break
12
13    return result

That small optimization matters when the file is huge and the requested lines are near the top.

Reading A Single Known Line

If you need just one line, a generator expression can keep the code compact.

python
1def read_one_line(path: str, target: int) -> str | None:
2    with open(path, "r", encoding="utf-8") as handle:
3        return next(
4            (line.rstrip("\n") for i, line in enumerate(handle, start=1) if i == target),
5            None,
6        )

This still scans from the top, but it stops as soon as the target line is reached.

linecache Can Be Useful For Repeated Access

Python also provides linecache, which caches file contents by line number.

python
import linecache

print(linecache.getline("example.txt", 10).rstrip("\n"))

This can be convenient for repeated lookups in the same file, but it is easy to misuse if the file changes while your process is running, because cached results may become stale.

Large Files And Repeated Queries

If you repeatedly query many arbitrary line numbers in a very large file, the real optimization is to build an index of byte offsets. That is more advanced, but the idea is simple: scan the file once, record where each line starts, and then seek directly to the offsets later.

That approach is worth the complexity only when repeated random access genuinely matters.

Encoding And Newlines Still Matter

Always open the file with the correct encoding when line content matters. If you use text mode, Python handles newline decoding for you, and rstrip("\n") is often enough for clean output. If the file can contain Windows line endings, rstrip() or rstrip("\r\n") may be a better cleanup choice.

Common Pitfalls

The most common mistake is assuming text files allow direct random access by line number the same way arrays do. Another is forgetting that line numbering is usually one-based in user-facing contexts even though many APIs are zero-based elsewhere. Developers also sometimes use linecache on files that change underneath them and then wonder why the returned content is stale. Finally, for huge files, it helps to stop scanning once the highest requested line has been read.

Summary

  • Sequential scanning with enumerate is the standard reliable way to read specific text-file lines.
  • Stop early when the highest requested line number is known.
  • 'linecache is convenient for repeated lookups but can become stale if the file changes.'
  • Text files do not naturally provide constant-time random access by line number.
  • Build an index only when repeated large-file random access justifies the extra complexity.

Course illustration
Course illustration

All Rights Reserved.