Skip to main content

How to Read a File Line by Line in Python

Learn practical patterns for working with text files, logs, and large datasets in Python.
Jan 24, 2026  · 6 min read

Python offers several ways to read files line by line, and at first glance, they can all seem interchangeable. In practice, though, the choice you make affects memory usage, performance, and even how readable your code is. Some approaches scale cleanly to large files, while others introduce problems without making it obvious.

In this tutorial, you’ll learn the recommended way to read a file line by line in Python and why it should usually be your default. We’ll also look at a few alternatives, explain when they make sense, and call out common mistakes that tend to trip people up. By the end, you’ll be able to read files confidently and efficiently, whether you’re writing a quick script or doing something more involved.

If you remember just one pattern from this article, make it this one. In most situations, iterating directly over a file object is the simplest, safest, and most efficient way to read a file line by line, and it’s the approach you’ll see most often in real Python code.

At a basic level, a file object in Python is already an iterator. That means you can loop over it directly and get one line at a time:

with open("example.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line)

This does exactly what it looks like. Python opens the file and yields each line one by one as the loop runs. There’s no manual indexing, no extra function calls, and no hidden complexity.

One of the biggest advantages of this approach is memory efficiency. Python does not load the entire file into memory. Instead, it reads a single line, processes it, and moves on to the next. That makes this pattern safe even for very large files, such as logs or raw data exports.

It’s also the most Pythonic solution. Iterating directly over a file object is clear, readable, and immediately understandable to anyone familiar with Python. That matters as scripts grow or when other people need to read your code later.

Because of these benefits, this should be your default choice unless you have a very specific reason to do something else. It automatically handles large files, scales well as file sizes grow, and avoids unnecessary memory usage—all without adding extra complexity.

Handling Newlines and Whitespace When Reading Lines in Python

If you’ve ever printed lines from a file and noticed unexpected blank lines or wondered why strings don’t look quite right, you’ve run into Python’s newline behavior. This is one of the most common beginner pain points, and it’s worth understanding early. 

When Python reads a file line by line, each line usually ends with a newline character (\n). That newline is part of the line itself, not something Python adds later. 

For example, a file that looks like this:

apple
banana
cherry

is actually read as: 

apple\n, banana\n, and cherry\n.

This behavior preserves the original structure of the file, which is important when formatting matters. But when you’re processing text—probably comparing values, parsing data, or cleaning input—you often want to remove that extra whitespace.

Cleaning lines for processing

The most common solution is to strip whitespace before using each line:

with open("data.txt", encoding="utf-8") as file:
    for line in file:
        clean_line = line.strip()
        print(clean_line)

The strip() method removes leading and trailing whitespace, including spaces, tabs, and newline characters. This is usually what you want when:

  • Comparing lines to expected values
  • Converting strings to numbers
  • Building structured data from file contents

Common whitespace patterns

Depending on your use case, more targeted methods may be better:

  • line.strip() removes whitespace from both ends

  • line.rstrip() removes whitespace from the right side

  • line.rstrip("\n") removes only the newline character

For example, if indentation matters but trailing newlines don’t:

clean_line = line.rstrip("\n")

When not to strip lines

It’s just as important to know when not to strip whitespace. If you’re working with:

  • Preformatted text
  • Fixed-width files
  • Logs where spacing matters
  • Markdown or code snippets

Removing whitespace can break the structure of the data. In those cases, work with the raw lines and handle formatting intentionally.

A good rule of thumb: strip lines when you’re processing content; preserve whitespace when formatting matters.

How to Keep Track of Line Numbers in Python

Once you’re reading files line by line, it’s common to want to know which line you’re on. This is especially useful for logs, validation errors, and debugging messy input files.

Python makes this easy using the built-in enumerate() function:

with open("data.txt", encoding="utf-8") as file:
    for line_number, line in enumerate(file, start=1):
        print(line_number, line.strip())

Here’s what’s happening:

  • The file still yields one line at a time

  • enumerate() adds a counter alongside each line

  • start=1 matches how humans count lines

This pattern stays memory-efficient and works just as well for large files.

When line numbers matter

Tracking line numbers is especially useful for:

  • Logs: identifying where an event occurred
  • Validation: reporting exactly where bad data appears
  • Debugging: tracing parsing failures
  • User feedback: pointing to a specific line in an input file

Because enumerate() keeps the code clean and readable, it’s almost always better than managing a manual counter.

Using readline() to Read One Line at a Time in Python

Python also provides a more manual option: readline(). You won’t need it often, but understanding it helps you recognize when it is appropriate.

The readline() method reads a single line each time it’s called. When the file is exhausted, it returns an empty string:

with open("example.txt", encoding="utf-8") as file:
    line = file.readline()
    while line:
        print(line.strip())
        line = file.readline()

When readline() Makes Sense

readline() is useful when reading needs to be conditional or tightly controlled, such as:

  • Interactive programs
  • Stopping as soon as a condition is met
  • Mixing file reading with complex logic

For example:

with open("log.txt", encoding="utf-8") as file:
    while True:
        line = file.readline()
        if not line or "ERROR" in line:
            break
        print(line.strip())

Why it’s usually not better than the default loop

For most cases, this is still better:

for line in file:
    process(line)

It’s shorter, clearer, just as efficient, and harder to misuse. Think of readline() as a special-case tool, not a replacement for the standard loop.

Why readlines() Is Usually a Bad Idea for Large Files

The readlines() method reads the entire file into memory and returns a list of lines:

with open("example.txt", encoding="utf-8") as file:
    lines = file.readlines()

This works for small files—but it doesn’t scale.

Because the entire file is loaded at once:

  • Memory usage grows with file size
  • Large files can slow your program or crash it
  • Problems often appear only in production

When readlines() is acceptable

It’s reasonable when:

  • The file is guaranteed to be small
  • You truly need all lines at once
  • The size is predictable and bounded

Otherwise, iterating line by line is almost always the better choice.

Common Mistakes When Reading Files Line by Line

Most issues come from a few small oversights:

  • Forgetting to close files → Use with

  • Loading entire files unintentionally → Avoid read() and readlines()

  • Ignoring encodings → Specify UTF-8 explicitly

  • Confusing text and binary modes → Use "r" for text, "rb" for binary

Once you’re aware of these, they’re easy to avoid.

Best Practices for Reading Files Line by Line in Python

Before wrapping up, here’s a quick checklist to keep your code clean and reliable:

  • Use the file object as an iterator by default
  • Strip whitespace intentionally, not automatically
  • Avoid loading entire files unless necessary
  • Handle encodings explicitly when working with text

These habits scale from quick scripts to production pipelines.

Conclusion

When it comes to reading a file line by line in Python, there’s a clear default: iterate directly over the file object. It’s simple, memory-efficient, and expressive enough to handle everything from small text files to massive logs.

Python’s design makes this pattern feel natural. You don’t need special utilities or complex logic because the language handles the hard parts for you. Most problems arise not from Python itself, but from overcomplicating a task that already has a clean solution.

Stick to the iterator-based approach, be intentional about whitespace and encodings, and your file-reading code will stay readable and be easy to reason about.

FAQs

Is reading a file line by line always slower than reading it all at once?

No. In fact, for large files, reading line by line is often faster overall because it avoids memory pressure. Loading an entire file into memory can slow your program down or cause it to crash, while line-by-line iteration keeps memory usage constant.

Why does Python include newline characters (\n) in each line?

Because Python preserves the file exactly as it exists on disk. Newlines are part of the data, not formatting added later. This makes file reading predictable and flexible—you decide when and how to clean the text, instead of Python guessing for you.

Should I always use strip() when reading lines?

Not always. Use strip() when you’re processing values, comparing strings, or cleaning input. Avoid it when whitespace carries meaning, such as in logs, formatted text, fixed-width files, or code snippets.

Is readline() ever better than for line in file?

Rarely but sometimes. readline() makes sense when reading needs to stop conditionally or interactively. For most batch processing tasks, the standard loop is clearer, safer, and just as efficient.

Think of readline() as a tool for edge cases, not a general replacement.

What’s the biggest mistake people make when reading files line by line?

Overcomplicating it. Most bugs come from loading entire files unnecessarily, mishandling encodings, or adding manual counters and state where Python already provides a clean solution.

Topics

Learn Python with DataCamp

Track

Associate Python Developer

32 hr
Learn Python for software development, from writing functions to defining classes. Get the necessary skills to kickstart your developer career!
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

Tutorial

Python Write to File: How to Work With Text, CSV, and JSON Files Safely

Learn how to write to files in Python using built-in tools, common patterns, and best practices for real-world applications.
Oluseye Jeremiah's photo

Oluseye Jeremiah

Tutorial

Importing and Writing Text Files in Python

This article covers different ways to import text files into Python using Python, NumPy, and Python’s built-in methods. It also covers how to convert these into lists.
Adam Shafi's photo

Adam Shafi

Tutorial

A Comprehensive Guide on How to Line Break in Python

Learn how to create a line break for a string in Python and create proper indentation using backslashes, parentheses, and other delimiters.
Amberle McKee's photo

Amberle McKee

Tutorial

Python Tutorial for Beginners

Get a step-by-step guide on how to install Python and use it for basic data science functions.
Matthew Przybyla's photo

Matthew Przybyla

Tutorial

Logging in Python Tutorial

Learn about the fundamentals of Logging in Python.
Aditya Sharma's photo

Aditya Sharma

code-along

Language Pattern Analysis in Python

In this session we use text analysis to look at language patterns in a review dataset.
Richie Cotton's photo

Richie Cotton

See MoreSee More