Python online course

Read a File into a List of Lines in Python

Learn how to use open(), readlines(), enumerate(), and string methods to load, inspect, clean, and process file lines safely in Python.

A text file can be represented in Python as a list in which each item is one line of text. This is useful when you need to inspect lines, access them by index, process them more than once, sort them, filter them, or transform their contents.

Each item in the list is a string. For example, a three-line file can become a list containing three strings:

["Have a nice day!\n", "You too!\n", "Thanks!"]

The first two strings commonly contain a newline character at the end. The final string has a newline only if the source file ends with one.

Open a file with a context manager

Python's built-in open() function opens a file and returns a file object. A file object provides methods for reading the file's contents. The "r" argument selects read mode; read mode is also the default, but writing it explicitly makes the purpose clear.

A with statement creates a context manager around the file operation:

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

When the indented block finishes, Python closes the file automatically. The file is also closed if an error occurs inside the block. This is safer than opening a file and relying on a later file.close() call.

The encoding argument tells Python how to decode the file's bytes into text. UTF-8 is a common choice, but use the encoding used by the source file when it is known.

Use readlines() to create the list

readlines() reads the remaining lines from a file object and returns them as a list of strings. In the usual case, every string except possibly the final one retains its line-ending character.

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

print(lines)

If new_file.txt contains:

Have a nice day!
You too!
Thanks!

the displayed list will usually look similar to this:

['Have a nice day!\n', 'You too!\n', 'Thanks!']

The displayed \n is escaped newline notation. It is how Python shows a newline character inside the representation of a string; it does not mean that the two visible characters backslash and n were necessarily stored in the file.

Inspect the resulting list

A list is ordered and mutable, so you can inspect its length, access an item by index, and reuse it for several operations.

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

print(lines)
print(len(lines))
print(type(lines))
print(type(lines[0]))
print(lines[0])

For a three-line file, len(lines) is 3. The type of lines is list, and the type of an individual element such as lines[0] is str. Indexing starts at zero, so lines[0] is the first line.

Iterate through lines with enumerate()

A for loop visits each string in the list. The built-in enumerate() helper supplies both an index and the corresponding line. Using start=1 produces line numbers that are convenient for people to read.

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

for number, line in enumerate(lines, start=1):
    print(f"Line {number}: {line}")

Because line may already end with a newline and print() adds its own newline, this can produce a blank-looking gap between output lines. Clean the line ending or control print()'s ending to avoid that effect.

A manually incremented counter is possible, but enumerate() keeps the counter synchronized with the loop:

number = 1
for line in lines:
    print(number, line)
    number += 1

Remove trailing newline characters

There are two common cleaning choices. Use strip() when all leading and trailing whitespace should be removed. Use rstrip("\r\n") when only the line-ending characters should be removed.

for number, line in enumerate(lines, start=1):
    cleaned_line = line.rstrip("\r\n")
    print(f"Line {number} - {cleaned_line}")

\n is a common newline character. Text from Windows may use the two-character sequence \r\n, so rstrip("\r\n") handles either carriage-return or newline characters at the right side.

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

for number, line in enumerate(lines, start=1):
    print(number, line.rstrip("\r\n"))
MethodWhat it removesWhen to use it
strip()Whitespace from both ends, including spaces, tabs, and line endingsUse when surrounding whitespace is not meaningful
rstrip()Whitespace from the right side when no character set is suppliedUse when all trailing whitespace should be discarded
rstrip("\r\n")Only carriage-return and newline characters from the right sideUse when leading or trailing spaces in the actual content must be preserved

For example, if a line intentionally contains spaces around its words, strip() removes those spaces, while rstrip("\r\n") leaves them in place. Choose the method according to whether those spaces are data or unwanted formatting.

Use the list for repeated processing

Once the lines are in a list, you can perform operations that benefit from retaining every line:

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

clean_lines = [line.rstrip("\r\n") for line in lines]
nonempty_lines = [line for line in clean_lines if line]
alphabetical_lines = sorted(nonempty_lines)

print(clean_lines)
print(nonempty_lines)
print(alphabetical_lines)

This approach supports indexed access, such as lines[2], and lets you loop over the same data multiple times. It also makes it straightforward to sort, filter, or create transformed versions of the original list.

Choose readlines() appropriately

readlines() loads all remaining lines into memory at once. That is convenient for short and medium-sized files, especially when you need random access or repeated processing. For a very large file, retaining every line may use more memory than necessary.

ApproachResultMemory behaviorBest use
readlines()A list of line stringsLoads all lines into memoryWhen you need the complete list, indexes, sorting, or repeated passes
read()One string containing the remaining file contentsLoads the complete text into memoryWhen you need to treat the file as one block of text
Direct iteration over the file objectOne line at a time in a loopProcesses progressively without storing all linesLarge files or one-pass processing

For streaming processing, iterate over the file object directly instead of creating a list:

with open("new_file.txt", "r", encoding="utf-8") as file:
    for number, line in enumerate(file, start=1):
        print(number, line.rstrip("\r\n"))

Direct iteration is preferable when you do not need all lines available at the same time. It still visits lines in order and provides the same line-ending behavior.

Handle paths, encodings, and common errors

A relative path is interpreted from the program's current working directory, not necessarily from the directory containing your Python source file. For example, "new_file.txt" means Python will look for that file in the current working directory. Check the spelling and location, or provide the correct relative or absolute path.

Typical file-reading problems include:

  • FileNotFoundError: The filename is misspelled, or the file is not in the current working directory. Confirm the location and use the correct relative or absolute path.
  • PermissionError: The operating system does not allow the program to read the file. Check permissions or choose a readable file.
  • UnicodeDecodeError: The file's encoding does not match the encoding used by open(). Specify the known encoding, such as encoding="utf-8", or use the encoding appropriate to the source.
  • Unexpected blank lines: The string already contains a newline and print() adds another. Use line.rstrip("\r\n") or print with end="".
  • Missing spaces: strip() removed meaningful surrounding whitespace. Use rstrip("\r\n") when only line endings should be removed.
  • Excessive memory use: readlines() stored a large file in one list. Iterate over the open file directly when retaining every line is unnecessary.

Complete example

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

print("List representation:")
print(lines)
print(f"Number of lines: {len(lines)}")

print("Cleaned lines:")
for number, line in enumerate(lines, start=1):
    print(f"Line {number} - {line.rstrip(chr(10)).rstrip(chr(13))}")

The expression line.rstrip(chr(10)).rstrip(chr(13)) removes newline and carriage-return characters in two steps. In ordinary Python code, line.rstrip("\r\n") is shorter and directly communicates that both common line-ending characters should be removed.

Key points

  • Use open() with a with statement to obtain and safely manage a file object.
  • Use readlines() when you need a list containing one string per line.
  • Line strings commonly retain their newline characters, and the final line may not have one.
  • Use enumerate(lines, start=1) for human-friendly line numbers.
  • Use strip() to remove surrounding whitespace, or rstrip("\r\n") to remove only line endings.
  • Iterate over the file object directly for large files when a complete list is unnecessary.
  • Check paths, permissions, and text encoding when file reading fails.