How to Read a Specific Line from a Text File in Python

To read a specific line from a text file in Python, loop over the file with enumerate(f, start=1) and return the line when the counter matches. It streams the file, so size doesn’t matter. linecache.getline(path, n) is the one-call option:

import linecache
line = linecache.getline("orders.log", 3)   # 3rd line, '' if missing

To check the behaviour of each method, including what happens past the end of the file, I ran them all on Python 3.12.5.

You’ll see the enumerate function, a side-by-side of readlines, islice and linecache, picking several lines or a range, the linecache caching trap, and how each copes with a million-line log.

Read a specific line from a file with enumerate()

Line numbers people use start at 1, so pass start=1. The function stops reading as soon as it finds the line and returns None if the file is shorter:

def read_line(path, line_number):
    """Return line `line_number` (1 = first line) without the newline, or None."""
    with open(path, encoding="utf-8") as f:
        for number, line in enumerate(f, start=1):
            if number == line_number:
                return line.rstrip("\n")
    return None

print(read_line("orders.log", 3))
print(read_line("orders.log", 8))
print(read_line("orders.log", 50))

Output:

2026-10-06 09:00:03 INFO order 1003 shipped to Boston
2026-10-06 09:00:08 INFO order 1008 shipped to Austin
None
Command Prompt output of a Python function reading line 3 and line 8 of a log file with enumerate, and None for line 50
Lines 3 and 8 of the order log print, and asking for line 50 of an 8-line file returns None.

rstrip("\n") removes the line break but keeps other spaces. For the line-by-line pattern in general, see reading a file line by line in Python.

readlines(), islice() and linecache compared

Three other approaches give the same line 5, but they behave very differently when the line doesn’t exist:

import linecache
from itertools import islice

path, n = "orders.log", 5

with open(path, encoding="utf-8") as f:
    print("readlines:", f.readlines()[n - 1].rstrip())

with open(path, encoding="utf-8") as f:
    print("islice:   ", next(islice(f, n - 1, None)).rstrip())

print("linecache:", linecache.getline(path, n).rstrip())

# asking for a line that doesn't exist
with open(path, encoding="utf-8") as f:
    print("islice 50:   ", repr(next(islice(f, 49, None), None)))
print("linecache 50:", repr(linecache.getline(path, 50)))
with open(path, encoding="utf-8") as f:
    try:
        f.readlines()[49]
    except IndexError as err:
        print("readlines 50: IndexError:", err)

Output:

readlines: 2026-10-06 09:00:05 INFO order 1005 shipped to Reno
islice:    2026-10-06 09:00:05 INFO order 1005 shipped to Reno
linecache: 2026-10-06 09:00:05 INFO order 1005 shipped to Reno
islice 50:    None
linecache 50: ''
readlines 50: IndexError: list index out of range
Command Prompt output of Python readlines, itertools.islice and linecache reading line 5, then their results for a missing line
All three return the order 1005 line; for line 50, islice gives None, linecache gives an empty string, and readlines raises IndexError.

linecache returning '' can hide a bug, because a real blank line also prints as nothing. When I only need the start or end of a file, I use the dedicated recipes for reading the first line of a file.

How do I read multiple specific lines from a file?

Put the line numbers in a set and collect matches in one pass. For a continuous range, islice() is simpler, but remember its start is 0-based:

from itertools import islice

wanted = {2, 4, 7}
with open("orders.log", encoding="utf-8") as f:
    picked = {n: line.rstrip() for n, line in enumerate(f, start=1) if n in wanted}
for n, line in picked.items():
    print(n, line)

print("--- lines 3 to 5 ---")
with open("orders.log", encoding="utf-8") as f:
    for line in islice(f, 2, 5):          # 0-based start, end not included
        print(line.rstrip())

Output:

2 2026-10-06 09:00:02 INFO order 1002 shipped to Seattle
4 2026-10-06 09:00:04 INFO order 1004 shipped to Tampa
7 2026-10-06 09:00:07 INFO order 1007 shipped to Mesa
--- lines 3 to 5 ---
2026-10-06 09:00:03 INFO order 1003 shipped to Boston
2026-10-06 09:00:04 INFO order 1004 shipped to Tampa
2026-10-06 09:00:05 INFO order 1005 shipped to Reno
Command Prompt output of Python reading lines 2, 4 and 7 of a file into a dict, then lines 3 to 5 with islice
Lines 2, 4 and 7 come back keyed by number, and islice(f, 2, 5) prints lines 3, 4 and 5.

To skip header rows before processing, see skipping the first line in a file.

Why does linecache return an old line?

linecache keeps the whole file in memory after the first call. If the file changes, you’ll keep getting the old content until you call checkcache():

import linecache
from pathlib import Path

print(linecache.getline("orders.log", 1).rstrip())

Path("orders.log").write_text("2026-10-06 10:00:00 INFO file was rotated\n", encoding="utf-8")
print(linecache.getline("orders.log", 1).rstrip())     # still the cached copy

linecache.checkcache("orders.log")
print(linecache.getline("orders.log", 1).rstrip())     # fresh read

Output:

2026-10-06 09:00:01 INFO order 1001 shipped to Denver
2026-10-06 09:00:01 INFO order 1001 shipped to Denver
2026-10-06 10:00:00 INFO file was rotated

That makes it a poor fit for log files that are still being written. To change a line rather than read it, see replacing a specific line in a file.

Read a specific line from a large file

Here’s line 750,000 of a million-line log, read four ways, with time and peak memory measured by tracemalloc:

import linecache
import time
import tracemalloc
from itertools import islice
from pathlib import Path

with open("big.log", "w", encoding="utf-8") as f:
    for i in range(1_000_000):
        f.write(f"2026-10-06 INFO request {i} from 10.0.{i % 256}.{i % 200} took {i % 900} ms\n")
print(f"big.log: {Path('big.log').stat().st_size / 1_048_576:.1f} MB, 1,000,000 lines")

def run(label, fn):
    tracemalloc.start()
    start = time.perf_counter()
    line = fn()
    took = time.perf_counter() - start
    peak = tracemalloc.get_traced_memory()[1] / 1_048_576
    tracemalloc.stop()
    print(f"{label:<10} {took * 1000:8.1f} ms  peak {peak:7.1f} MB  -> {line.split()[3]}")

n = 750_000
run("readlines", lambda: open("big.log", encoding="utf-8").readlines()[n - 1])
run("enumerate", lambda: next(l for i, l in enumerate(open("big.log", encoding="utf-8"), 1) if i == n))
run("islice", lambda: next(islice(open("big.log", encoding="utf-8"), n - 1, None)))
run("linecache", lambda: linecache.getline("big.log", n))

Output:

big.log: 58.0 MB, 1,000,000 lines
readlines     541.6 ms  peak   104.2 MB  -> 749999
enumerate     499.6 ms  peak     0.0 MB  -> 749999
islice        299.9 ms  peak     0.0 MB  -> 749999
linecache     672.9 ms  peak   104.2 MB  -> 749999
Command Prompt output timing Python readlines, enumerate, islice and linecache reading line 750,000 of a large log file
All four return request 749999; readlines and linecache use far more peak memory than islice and enumerate, which stream the file.

Timings change from run to run, but the memory gap is what matters: readlines() and linecache load every line. For the last lines of a big file, use reading the last line of a file instead.

Which method should you use?

MethodMissing lineMemoryBest for
enumerate(f, 1) loopYour choice (None)One lineMost cases
islice(f, n-1, None)None with a defaultOne lineRanges, big files
linecache.getline()''Whole file, cachedRepeated lookups in a static file
f.readlines()[n-1]IndexErrorWhole fileSmall files you already loaded

More file-reading recipes worth bookmarking:

Frequently asked questions

How do I read a specific line from a file in Python?

Loop with for n, line in enumerate(f, start=1) and return the line when n matches, or use linecache.getline(path, n).

Are line numbers 0-based or 1-based?

linecache and enumerate(..., start=1) are 1-based. List indexes and islice() are 0-based, so use n - 1.

What happens if the line number is past the end of the file?

readlines() raises IndexError, linecache returns an empty string, and islice returns the default you pass to next().

How do I read lines 10 to 20 of a file?

Use islice(f, 9, 20), which yields lines 10 through 20.

What is the fastest way to read one line of a huge file?

Stream it with islice() or an enumerate loop. Avoid readlines(), which loads the whole file.

Where is linecache documented?

See the linecache module in the Python docs.