Чтение CSV-файлов в Python
Эта статья — детальный разбор именно чтения CSV: все способы, все полезные опции и реальные сценарии. Если нужно ещё и записывать, или собирать аналитику с pandas — смотрите Модуль csv — работа с CSV-файлами в Python и Работа с CSV-файлами в Python: практическое руководство.
Базовый шаблон
Самый минимальный код для чтения CSV:
import csv
with open('data.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
Что здесь важно:
open(..., newline='')— обязательно. Без этогоcsvнеправильно обрабатывает переводы строк (особенно на Windows).encoding='utf-8'— явная кодировка. Не полагайтесь на дефолт системы.with— гарантия, что файл закроется.csv.reader(f)возвращает итератор; читается лениво, строка за строкой.
Что возвращает csv.reader
Каждая строка — это список строк (list[str]). Все значения — текст, типов
нет.
id,name,age
1,Айдос,21
2,Гульнара,19
--> [['id', 'name', 'age'],
['1', 'Айдос', '21'],
['2', 'Гульнара', '19']]
Преобразование типов — задача программиста:
import csv
with open('users.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
next(reader) # пропустить заголовки
for row in reader:
id_, name, age = row
age = int(age)
print(name, age)
Чтение со словарями: csv.DictReader
DictReader берёт первую строку как заголовки и выдаёт каждую строку как
словарь. Это удобнее, чем помнить индексы колонок.
import csv
with open('users.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['name'], row['age'])
Если заголовков в файле нет — задайте сами:
reader = csv.DictReader(f, fieldnames=['id', 'name', 'age'])
И поля заголовков всегда доступны через reader.fieldnames.
Пропуск заголовков
Способ 1 — через next:
import csv
with open('data.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
...
Способ 2 — собрать zip(header, row) в словарь вручную:
import csv
with open('data.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
record = dict(zip(header, row))
print(record)
Способ 3 (рекомендуемый): просто DictReader.
Другой разделитель
Файлы из Excel в локали с запятой как десятичным разделителем используют ;:
import csv
with open('export.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f, delimiter=';')
for row in reader:
print(row)
То же для DictReader:
reader = csv.DictReader(f, delimiter=';')
Если разделитель неизвестен — есть csv.Sniffer:
import csv
with open('mystery.csv', newline='', encoding='utf-8') as f:
sample = f.read(2048)
f.seek(0)
dialect = csv.Sniffer().sniff(sample)
reader = csv.reader(f, dialect)
has_header = csv.Sniffer().has_header(sample)
if has_header:
next(reader)
for row in reader:
print(row)
Кодировки
Самый частый источник боли. Шпаргалка:
Источник Кодировка
--------------------------- ---------------
современная веб-выгрузка utf-8
Excel "Сохранить как CSV UTF-8" utf-8-sig (с BOM)
Excel "CSV (разделители - запятые)" в RU-локали cp1251 ; разделитель
1С, банк-клиент cp1251 или windows-1251
зарубежные госсайты utf-8 или latin-1
При UnicodeDecodeError:
# пробуйте по очереди:
for enc in ('utf-8', 'utf-8-sig', 'cp1251', 'latin-1'):
try:
with open(path, encoding=enc, newline='') as f:
next(csv.reader(f))
print('Подходит:', enc)
break
except UnicodeDecodeError:
continue
Пропуск некорректных строк
В реальных данных встречаются битые строки. Стандартный способ — обработать их в try/except:
import csv
with open('data.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for line_no, row in enumerate(reader, start=2):
try:
age = int(row['age'])
except (ValueError, KeyError) as e:
print(f'Пропускаю строку {line_no}: {e}')
continue
# ... обработка ...
start=2 — потому что строка 1 это заголовок.
Потоковая обработка больших файлов
csv.reader не загружает весь файл сразу — он лениво читает по одной строке.
Это значит, что файл хоть на 100 ГБ обработается с памятью на одну строку:
import csv
total = 0
with open('huge.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
total += int(row['amount'])
print(total)
Не вызывайте list(reader) без необходимости — это сразу всё в память.
Практический пример: импорт пользователей в БД
import csv
import sqlite3
conn = sqlite3.connect('app.db')
cur = conn.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER, name TEXT, age INTEGER)')
with open('users.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
batch = []
for row in reader:
batch.append((int(row['id']), row['name'], int(row['age'])))
if len(batch) >= 1000:
cur.executemany('INSERT INTO users VALUES (?, ?, ?)', batch)
batch.clear()
if batch:
cur.executemany('INSERT INTO users VALUES (?, ?, ?)', batch)
conn.commit()
conn.close()
Пачками по 1000 — намного быстрее, чем по одной строке.
Практический пример: выгрузка по фильтру
Прочитать продажи за май и посчитать, сколько штук каждого продукта продалось:
import csv
from collections import Counter
counter = Counter()
with open('sales.csv', newline='', encoding='utf-8') as f:
for row in csv.DictReader(f):
if row['date'].startswith('2026-05'):
counter[row['product']] += int(row['amount'])
for product, qty in counter.most_common():
print(f'{product}: {qty}')
Размер ячейки
По умолчанию csv ограничивает поле в 128 КБ. Если данные большие
(например, JSON-строки в столбце) — увеличьте лимит:
import csv
import sys
csv.field_size_limit(min(sys.maxsize, 10**8))
Подводные камни
Предупреждение
Забыли ``newline=““`` — получаете лишние пустые строки на Windows.
Все значения строки. Никакого «умного» преобразования. Числа — через
int()/float(), даты — черезdatetime.strptime.Не игнорируйте кодировку. Без явного
encodingPython берёт системный дефолт, который на разных машинах разный.BOM в начале файла. Если первый ключ выглядит как
'id'— используйтеencoding='utf-8-sig'.``DictReader`` и дубликаты столбцов. Если в заголовке две одинаковые колонки, останется только последняя. Проверяйте заголовки.
Смотрите также
Модуль csv — работа с CSV-файлами в Python — справочник по модулю csv
Работа с CSV-файлами в Python: практическое руководство — практика, pandas, кодировки
Работа с файлами Python — общая работа с файлами
Примечание
Лицензия и источники
Часть материала адаптирована из официальной документации Python (https://docs.python.org/3/library/csv.html), доступной под Python Software Foundation License Version 2 (PSF License). Адаптация, переработка, оригинальные примеры и пояснения — © AlashEd Wiki.