Задача «посчитать строки» в Python встречается в двух контекстах: строки в файле и строки в строковой переменной. В обоих случаях решение укладывается в одну-две строчки кода, но выбор способа зависит от размера данных. Для файла в 100 строк подойдёт любой вариант. Для файла в 10 ГБ — только тот, что не загружает его целиком в память.
Ниже — пять рабочих способов с примерами кода, сравнением по скорости и памяти, и рекомендацией, какой когда использовать.
- Способ 1: readlines() + len()
- Как это работает
- Когда использовать
- Минус
- Способ 2: генераторное выражение + sum()
- Как это работает
- Когда использовать
- Способ 3: enumerate()
- Как это работает
- Нюанс
- Способ 4: splitlines() для строковых переменных
- Почему splitlines(), а не split(«\n»)
- Способ 5: subprocess + wc (Linux/macOS)
- Когда использовать
- Минус
- Сравнение способов
- Практические примеры
- Подсчёт непустых строк
- Подсчёт строк, содержащих определённое слово
- Подсчёт строк кода в Python-файле (без пустых и комментариев)
- Подсчёт строк во всех .txt файлах папки
- FAQ
- Какой способ самый быстрый?
- Можно ли посчитать строки без чтения файла в память?
- Почему readlines() показывает другое число строк, чем splitlines()?
- Как не считать пустые строки?
- Как посчитать строки кода без комментариев?
Способ 1: readlines() + len()
Самый очевидный вариант. Читаем все строки файла в список, считаем длину списка:
with open("data.txt", "r", encoding="utf-8") as f:
line_count = len(f.readlines())
print(line_count)
Как это работает
readlines() читает весь файл и возвращает список, где каждый элемент — одна строка (включая символ на конце).
len() возвращает количество элементов в списке.
Когда использовать
- Файл небольшой (до нескольких мегабайт)
- Вам всё равно нужны сами строки для дальнейшей обработки
Минус
Весь файл загружается в память. Файл в 2 ГБ займёт ≈2 ГБ оперативки — и скрипт может упасть с MemoryError.
Способ 2: генераторное выражение + sum()
Элегантный однострочник, который не загружает файл целиком в память:
with open("data.txt", "r", encoding="utf-8") as f:
line_count = sum(1 for _ in f)
print(line_count)
Как это работает
Файловый объект в Python — итератор. Цикл for _ in f перебирает строки по одной, не создавая список в памяти. Генераторное выражение (1 for _ in f) отдаёт единицу на каждую строку, а sum() складывает их.
Когда использовать
- Файлы любого размера — потребление памяти минимальное и постоянное
- Нужен только подсчёт, сами строки не важны
Это рекомендуемый универсальный способ для большинства задач.
Способ 3: enumerate()
Вариация предыдущего способа, полезная, когда нужно одновременно считать строки и что-то делать с каждой:
with open("data.txt", "r", encoding="utf-8") as f:
for count, line in enumerate(f, start=1):
pass # здесь можно обрабатывать каждую строку
print(count)
Как это работает
enumerate(f, start=1) нумерует строки начиная с 1. После завершения цикла переменная count содержит номер последней строки — то есть общее количество.
Нюанс
Если файл пустой, переменная count не будет создана и код упадёт с NameError. Безопасный вариант:
count = 0
with open("data.txt", "r", encoding="utf-8") as f:
for count, _ in enumerate(f, start=1):
pass
print(count) # 0 для пустого файла
Способ 4: splitlines() для строковых переменных
Если строки нужно посчитать не в файле, а в обычной строковой переменной:
text = """Первая строка
Вторая строка
Третья строка"""
line_count = len(text.splitlines())
print(line_count) # 3
Почему splitlines(), а не split(«\n»)
splitlines() корректно обрабатывает все виды переносов строк: (Unix),
(Windows),
(старый Mac). А
split(" — только
"). Кроме того,
splitlines() не создаёт лишний пустой элемент, если строка заканчивается переносом.
Тот же подход работает с pathlib:
from pathlib import Path
line_count = len(Path("data.txt").read_text(encoding="utf-8").splitlines())
Компактно, но загружает файл целиком — подходит только для небольших файлов.
Способ 5: subprocess + wc (Linux/macOS)
На Unix-системах можно использовать утилиту wc -l, которая считает строки на уровне ОС — это самый быстрый способ для больших файлов:
import subprocess
result = subprocess.run(["wc", "-l", "data.txt"], capture_output=True, text=True)
line_count = int(result.stdout.split()[0])
print(line_count)
Когда использовать
- Linux или macOS
- Огромные файлы (гигабайты и больше)
- Скорость критична
Минус
Не работает на Windows без WSL или Cygwin. Для кроссплатформенного кода лучше способ 2.
Сравнение способов
| Способ | Память | Скорость | Кроссплатформенность | Когда выбирать |
|---|---|---|---|---|
len(f.readlines()) |
Весь файл в RAM | Быстро для малых файлов | Да | Малые файлы + нужны сами строки |
sum(1 for _ in f) |
Постоянная, минимальная | Быстро | Да | Универсальный выбор |
enumerate() |
Постоянная, минимальная | Быстро | Да | Подсчёт + обработка строк |
splitlines() |
Весь текст в RAM | Быстро для малых строк | Да | Строковые переменные, pathlib |
wc -l |
Минимальная | Самый быстрый | Только Unix | Гигабайтные файлы на Linux/macOS |
Практические примеры
Подсчёт непустых строк
with open("data.txt", "r", encoding="utf-8") as f:
non_empty = sum(1 for line in f if line.strip())
print("Непустых строк:", non_empty)
Подсчёт строк, содержащих определённое слово
with open("log.txt", "r", encoding="utf-8") as f:
errors = sum(1 for line in f if "ERROR" in line)
print("Строк с ошибками:", errors)
Подсчёт строк кода в Python-файле (без пустых и комментариев)
with open("script.py", "r", encoding="utf-8") as f:
code_lines = sum(
1 for line in f
if line.strip() and not line.strip().startswith("#")
)
print("Строк кода:", code_lines)
Подсчёт строк во всех .txt файлах папки
from pathlib import Path
total = 0
for file in Path("./data").glob("*.txt"):
with open(file, "r", encoding="utf-8") as f:
total += sum(1 for _ in f)
print("Всего строк во всех файлах:", total)
FAQ
sum(1 for _ in f) и len(f.readlines()) минимальна — доли секунды. Для гигабайтных файлов на Linux/macOS быстрее всего wc -l через subprocess, потому что утилита написана на C и работает на уровне ОС.sum(1 for _ in f)) читает файл построчно — в памяти находится только одна строка в каждый момент. Способ 5 (wc -l) вообще не читает файл в Python — это делает системная утилита.
, и
, и
). splitlines() распознаёт все виды переносов, а итератор файла — только
(в текстовом режиме Python конвертирует
в
, но одиночные
может пропустить). Если результаты расходятся — проверьте кодировку и формат переносов в файле.if line.strip() в генераторное выражение: sum(1 for line in f if line.strip()). Метод strip() убирает пробелы и переносы — пустая строка после него превращается в пустую строку "", которая в булевом контексте даёт False.#): sum(1 for line in f if line.strip() and not line.strip().startswith("#")). Для точного подсчёта с учётом многострочных строк и docstring используйте модуль ast или утилиту pygount.