How to Read the Last Line of a File in Python

To read the last line of a file in Python without storing the entire file in memory:

  1. Loop through each line in the file.
  2. Skip each line until you reach the last line.
  3. Save the last line in memory.

Here is an example:

with open("filename.txt") as file:
    for line in file:
        pass
    last_line = line

The Naive Approach

The most naive approach to read the last line of a file in Python is:

  1. Read the entire file line by line into a list.
  2. Access the last element of that list.

Here is the code:

with open("example.txt", "r") as file:
    last_line = file.readlines()[-1]

Find the Last Line of a Large File in Python

If you have a big file you don’t want to store in memory or loop through the way you saw previously, you can rely on seeking the file.

To find the last line of a large file in Python by seeking:

  1. Open the file in binary mode.
  2. Seek to the end of the file.
  3. Jump back the characters to find the beginning of the last line.

Here is how it looks in the code:

import os

with open("example.txt", "rb") as file:
    try:
        file.seek(-2, os.SEEK_END)
        while file.read(1) != b'\n':
            file.seek(-2, os.SEEK_CUR)
    except OSError:
        file.seek(0)
    last_line = file.readline().decode()

However, by looking at the code, it is not trivial to understand how it works.

How Does File Seeking Work in Python

To read the last line of a file by seeking in Python, the file reader is moved to the very last character of the file.

Then the reader jumps backward character by character until it reaches the beginning of the last line. Then it reads the last line into memory.

Here is an illustration of how the code finds the last line in a file with three lines of text:

Let’s take a look at the code in a bit more detail.

First of all, seeking means setting the file reader’s position in the file.

In Python, you can only seek binary files, so you need to read the file as a binary file.

The seek() method follows this syntax:

file.seek(offset, whence)

Where:

The offset specifies how many characters to move. Use a negative value to move backward.

The whence argument is an optional argument that can be set

  • os.SEEK_SET or 0—seek relative to the beginning of the file.
  • os.SEEK_CUR or 1—seek relative to the current position in the file.
  • os.SEEK_END or 2—seek relative to the end of the file.

First of all, let’s simplify the above code a bit by removing the error handling, and the os module constants:

with open("example.txt", "rb") as file:
    file.seek(-2, 2)
    while file.read(1) != b'\n':
        file.seek(-2, 1)
    last_line = file.readline().decode()

Now that you understand how the seek() method works, you can understand the code:

  • file.seek(-2, 2) means “Jump to the 2nd character before the end of the file”.
  • file.read(1) means “Read the character from the right”.
  • file.seek(-2, 1) means “Jump 2 characters left from the current character”.
  • b’\n’ is the line break character in binary mode.
  • file.readline().decode() reads the line and converts it from binary to string.

So the process is as follows:

  • The code first jumps to the very last character of the file.
  • It then checks if the character is a line break character.
  • If it is not, then it jumps back one character and checks again.
  • It repeats this until the line break is encountered, which suggests that the beginning of the last line is reached.
  • Then it stores the last line in memory.

Notice that seeking a file only works with binary files. This is why the file is read in binary mode. Also, notice that as you are dealing with a binary file, you need to jump two characters left to read one character to the right.

Now, let’s bring back the try-catch error handling to make sure the file is not exactly one line long. Because if it is, the seek() will never encounter a line break character as there are none. Let’s also use the os module’s constants SEEK_END and SEEK_CUR instead of plain 1 or 2:

import os

with open("example.txt", "rb") as file:
    try:
        file.seek(-2, os.SEEK_END)
        while file.read(1) != b'\n':
            file.seek(-2, os.SEEK_CUR)
    except OSError:
        file.seek(0)
    last_line = file.readline().decode()

Now you learned how the seeking approach works when reading the last line of a file in Python.

Conclusion

Today you learned 3 ways to read the last line of a file in Python:

  1. Skip through the file all the way to the last line.
  2. Read the entire file in memory, and access the last line.
  3. Seek to the end of the file and read the last line.

Pick one that best fits your needs.

I hope you find it useful. Thanks for reading!

Scroll to Top