The file.readlines([hint]) method reads all remaining lines from an open file stream and returns them as a list[str], where each element represents a single line containing its trailing newline delimiter.
Memory vs. Convenience Tradeoff: While readlines() provides instant random indexed access to all lines in a file, it loads the entire dataset into RAM at once. For multi-gigabyte files, prefer streaming lines with for line in f: to keep memory constant (O(1)).
The standard CPython signature for file.readlines() is:
file_object.readlines(hint=-1)
| Parameter | Type | Default | Behavior & Description |
|---|---|---|---|
hint |
int |
-1 |
Approximate upper bound on the number of bytes/characters to read. If negative or -1, reads all lines until EOF. If > 0, reads complete lines until total bytes exceed hint. |
| Return Value | list[str] |
— | A Python list of strings. Each line includes its terminating newline character (\n or \r\n), except possibly the final line if missing a trailing newline. |
When working with configuration files, CSV tables, or small datasets that fit comfortably in memory, readlines() provides immediate list conveniences such as slicing, sorting, reversing, and indexing:
with open("server.cfg", "r", encoding="utf-8") as fob:
lines = fob.readlines()
print("Total lines loaded:", len(lines))
print("First line:", repr(lines[0]))
print("Last line: ", repr(lines[-1]))
The optional hint integer controls the maximum volume of bytes read before readlines() halts line consumption. Importantly, Python completes the entire line that reaches or exceeds the threshold rather than cutting lines in half:
with open("data.txt", "r", encoding="utf-8") as fob:
# Read until approximately 30 bytes have been consumed
batch = fob.readlines(30)
print("Lines returned in batch:", len(batch))
for line in batch:
print("- ", line.rstrip("\n"))
Because each string produced by readlines() retains its terminating \n character, printing them directly with print() produces extra blank lines. Use list comprehensions with rstrip('\n') to sanitize strings:
with open("inventory.csv", "r", encoding="utf-8") as stream:
# rstrip('\n') removes only trailing newlines while preserving inner whitespace
clean_lines = [line.rstrip("\n") for line in stream.readlines()]
# Alternative: Filter out empty or whitespace-only lines simultaneously
non_empty = [line.strip() for line in clean_lines if line.strip()]
print("Cleaned lines ready for processing:", len(non_empty))
Choosing between Python's line-reading strategies depends on memory constraints and indexing requirements:
| Mechanism | Return Type | Memory Complexity | Random Indexing? | Recommended Architecture |
|---|---|---|---|---|
f.readlines() |
list[str] |
O(N) — Loads all lines | Yes (e.g. lines[5]) |
Small configuration files, sorting/reversing in-place. |
for line in f: |
Generator / Stream | O(1) — Single line buffer | No (sequential only) | Gold Standard for log parsers, ETL pipelines, large CSVs. |
f.readline() |
str (single line) |
O(1) per invocation | No | Peeking file headers, interactive CLI prompts. |
f.read().splitlines() |
list[str] |
O(N) — Loads entire string + list | Yes | Small files where newlines must be stripped automatically. |
Quickly separate a CSV header definition from the data rows using standard list slicing:
def parse_table_data(filepath: str) -> tuple[str, list[str]]:
with open(filepath, "r", encoding="utf-8") as f:
lines = f.readlines()
if not lines:
return "", []
header = lines[0].rstrip("\n")
body_rows = [r.rstrip("\n") for r in lines[1:] if r.strip()]
return header, body_rows
hdr, rows = parse_table_data("users.csv")
print("Header:", hdr)
print(f"Loaded {len(rows)} data records.")
Isolate critical errors from warning logs using in-memory list filtering:
def extract_critical_errors(log_path: str) -> list[str]:
with open(log_path, "r", encoding="utf-8") as log_file:
lines = log_file.readlines()
return [l.rstrip("\n") for l in lines if "[ERROR]" in l or "[CRITICAL]" in l]
failures = extract_critical_errors("system.log")
print(f"Found {len(failures)} critical failures needing inspection.")
Calling readlines() on a 10 GB file attempts to build millions of string objects in RAM simultaneously, causing immediate MemoryError and system swapping. Never use readlines() on files of unconstrained or unknown size — use for line in stream: instead.
Because Python's print() adds a newline by default, printing lines from readlines() outputs an empty space between every row. Pass end="" to print() or call .rstrip('\n') beforehand.
Run this complete test suite verifying list construction, newline handling, and byte hint constraints:
import tempfile
import os
class ReadlinesVerifier:
@staticmethod
def load_clean(path: str) -> list[str]:
with open(path, "r", encoding="utf-8") as stream:
return [l.rstrip("\n") for l in stream.readlines()]
# Verification unit assertions
with tempfile.TemporaryDirectory() as td:
v = ReadlinesVerifier()
test_file = os.path.join(td, "test.txt")
raw_data = "Alpha\nBeta\nGamma\n"
with open(test_file, "w", encoding="utf-8") as f:
f.write(raw_data)
# Test 1: Full list loading
with open(test_file, "r", encoding="utf-8") as f:
loaded = f.readlines()
assert loaded == ["Alpha\n", "Beta\n", "Gamma\n"]
# Test 2: Clean newline stripping
assert v.load_clean(test_file) == ["Alpha", "Beta", "Gamma"]
# Test 3: Byte hint limiting
with open(test_file, "r", encoding="utf-8") as f:
hinted = f.readlines(5) # Consumes first line (6 bytes with \n)
assert len(hinted) >= 1
print("All file.readlines() unit assertions passed successfully!")
Open in Google Colab View on GitHub
Run all readlines exercises interactively, test byte hint limiting, benchmark memory differences against generator line iteration, and filter structured datasets in Google Colab.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.