Модуль csv — работа с CSV-файлами в Python
Формат CSV (Comma Separated Values, «значения, разделённые запятыми») — самый распространённый способ обмена табличными данными между программами: Excel, Google Sheets, базы данных, веб-API экспорта. Если открыть такой файл в текстовом редакторе, мы увидим что-то вроде этого:
id,name,city,age
1,Айдос,Алматы,21
2,Гульнара,Астана,19
3,Ержан,Шымкент,24
Каждая строка — это запись, а поля внутри строки разделены запятой (или другим символом-разделителем — точка с запятой, табуляция и т. д.).
Стандартный модуль Python csv берёт на себя всю чёрную работу: правильно
обрабатывает кавычки, экранирование, переводы строк внутри ячеек и разные
диалекты CSV. Не пытайтесь парсить CSV через split(',') — это работает только
на тепличных данных и ломается при первой же запятой внутри значения.
Зачем нужен модуль csv
CSV выглядит обманчиво простым форматом, но в нём много нюансов:
поле может содержать запятую — тогда его берут в кавычки:
"Алматы, Казахстан";поле может содержать кавычки — их удваивают:
"Он сказал ""привет""";поле может содержать перенос строки;
разделителем может быть
;,\tили что угодно ещё (так называемые диалекты).
Модуль csv корректно обрабатывает всё это автоматически. Используйте его
всегда, когда работаете с CSV.
Совет
Если данные большие (миллионы строк) или нужны сложные операции (группировка,
слияние, агрегаты) — посмотрите в сторону библиотеки pandas. Для простого
чтения/записи стандартного csv достаточно и он быстрее по памяти.
Чтение CSV: csv.reader
csv.reader принимает файловый объект и возвращает итератор, который выдаёт
каждую строку как список строк.
import csv
with open('users.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
Вывод:
['id', 'name', 'city', 'age']
['1', 'Айдос', 'Алматы', '21']
['2', 'Гульнара', 'Астана', '19']
['3', 'Ержан', 'Шымкент', '24']
Важно
Обратите внимание на newline='' при открытии файла. Это обязательный
параметр для csv: без него на Windows можно получить лишние пустые строки
между записями.
Часто первая строка — это заголовки. Их можно прочитать отдельно:
import csv
with open('users.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
header = next(reader) # читаем заголовки
for row in reader: # дальше идут только данные
print(dict(zip(header, row)))
Чтение CSV: csv.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['city'])
Вывод:
Айдос — Алматы
Гульнара — Астана
Ержан — Шымкент
DictReader сам считывает первую строку как заголовки. Если их нет в файле,
можно задать вручную:
reader = csv.DictReader(f, fieldnames=['id', 'name', 'city', 'age'])
Запись CSV: csv.writer
Симметрично чтению — csv.writer записывает строки в файл.
import csv
rows = [
['id', 'name', 'city'],
[1, 'Айдос', 'Алматы'],
[2, 'Гульнара', 'Астана, Казахстан'], # внутри есть запятая — будет в кавычках
]
with open('out.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerows(rows)
Файл out.csv после запуска:
id,name,city
1,Айдос,Алматы
2,Гульнара,"Астана, Казахстан"
Видите — модуль сам поставил кавычки вокруг Астана, Казахстан.
Запись CSV: csv.DictWriter
Для записи словарей:
import csv
rows = [
{'id': 1, 'name': 'Айдос', 'city': 'Алматы'},
{'id': 2, 'name': 'Гульнара', 'city': 'Астана'},
]
with open('out.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['id', 'name', 'city'])
writer.writeheader()
writer.writerows(rows)
Диалекты и параметры
В разных программах CSV формируется немного по-разному. Excel в русской локали,
например, использует ; как разделитель, потому что в десятичных числах уже
есть запятая. Управлять этим можно через параметры или встроенные диалекты:
reader = csv.reader(f, delimiter=';', quotechar='"')
Самые полезные параметры:
delimiter— разделитель полей (по умолчанию,);quotechar— символ кавычек (по умолчанию");quoting— стратегия экранирования (csv.QUOTE_ALL,QUOTE_MINIMAL,QUOTE_NONNUMERIC,QUOTE_NONE);escapechar— символ экранирования, еслиquoting=QUOTE_NONE.
Встроенные диалекты: 'excel' (по умолчанию), 'excel-tab', 'unix'.
Практический пример: фильтрация CSV
Допустим, у нас есть файл orders.csv и нужно выбрать только заказы из Алматы
и сохранить в новый файл:
import csv
with open('orders.csv', newline='', encoding='utf-8') as src, \
open('orders_almaty.csv', 'w', newline='', encoding='utf-8') as dst:
reader = csv.DictReader(src)
writer = csv.DictWriter(dst, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
if row['city'] == 'Алматы':
writer.writerow(row)
Файл читается потоково — даже миллион строк уйдёт без проблем с памятью.
Подводные камни
Предупреждение
Кодировка. Файлы из Excel часто сохраняются в
cp1251илиutf-8-sig(с BOM в начале). Если получаетеUnicodeDecodeError— попробуйтеencoding='utf-8-sig'илиencoding='cp1251'.Числа остаются строками.
csv.readerне угадывает типы:'42'так и останется строкой. Преобразуйте вручную черезint(row['age']).``newline=““`` обязателен — иначе на Windows между строками появятся пустые записи.
Размер ячейки. По умолчанию модуль ограничивает поле 128 КБ. Для очень длинных значений вызовите
csv.field_size_limit(10**7).
Смотрите также
Чтение CSV-файлов в Python — углублённое чтение CSV
Работа с CSV-файлами в Python: практическое руководство — практическое руководство (с pandas)
Модуль json — работа с JSON в Python — альтернативный формат обмена данными
Работа с файлами Python — общие операции с файлами
Примечание
Лицензия и источники
Часть материала адаптирована из официальной документации Python (https://docs.python.org/3/library/csv.html), доступной под Python Software Foundation License Version 2 (PSF License). Адаптация, переработка, оригинальные примеры и пояснения — © AlashEd Wiki.