Python: уроки, справочник и задачи

CSV файл в Python: запись, чтение и словари

Раздел: Работа с файлами в Python · Обновлено 31.10.2026

CSV файл в Python читают и записывают встроенным модулем csv: он сам расставляет разделители и кавычки и превращает строки таблицы в списки или словари. В статье разобраны writer и reader, DictWriter и DictReader, дозапись в существующий файл, разделитель точка с запятой и кодировка, с которой таблица корректно открывается в Excel.

CSV файл в Python: запись, чтение и словари
Фото: Umulhidayah / CC BY-SA 4.0, Wikimedia Commons
Содержание статьи
  1. Как устроен формат CSV
  2. Запись списков через csv.writer
  3. Чтение через csv.reader
  4. Словари: DictWriter и DictReader
  5. Разделитель, кавычки и кодировка для Excel
  6. Когда лучше взять pandas
  7. Частые вопросы
    1. Почему в CSV появляются пустые строки между записями?
    2. Как прочитать только один столбец?
    3. Как записать в CSV числа с запятой в дробной части?
    4. Можно ли изменить строку прямо в CSV файле?

Как устроен формат CSV

CSV (Comma-Separated Values) - обычный текстовый файл, где каждая строка является записью таблицы, а значения внутри строки разделены запятой. Первая строка часто содержит названия столбцов. Такой файл открывается в любом редакторе, в Excel, LibreOffice и загружается в базы данных.

name,age,city
Kevin,28,Москва
Alice,23,"Ростов-на-Дону, центр"
Joe,34,"Кафе ""Ромашка"""

Если значение содержит запятую, перевод строки или кавычку, его заключают в двойные кавычки, а кавычки внутри удваивают. Из-за этих правил разбирать CSV через line.split(",") ненадежно: третья строка примера распадется на лишние столбцы. Модуль csv учитывает экранирование автоматически.

Модуль входит в стандартную библиотеку. Файл открывается обычной функцией open(), о режимах которой подробно рассказано в статье про чтение и запись файлов. Для CSV есть два обязательных правила: передавать newline="" и явно указывать кодировку.

Запись списков через csv.writer

Функция csv.writer(file) возвращает объект, у которого два метода: writerow() записывает одну строку из списка, writerows() принимает список строк, то есть двумерный список. Числа и другие типы перед записью превращаются в строки.

import csv

friends = [
    ["name", "age"],
    ["Kevin", 28],
    ["Alice", 23],
    ["Joe", 34],
]

with open("friends.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.writer(file)
    writer.writerows(friends)

Параметр newline="" нужен потому, что writer сам завершает строки символами \r\n. Без него на Windows файл получит лишнюю пустую строку после каждой записи.

Чтобы добавить запись в конец существующего файла, откройте его в режиме "a". Режим "w" стирает содержимое при открытии, это частая причина потерянных данных.

with open("friends.csv", "a", newline="", encoding="utf-8") as file:
    csv.writer(file).writerow(["Tima", 31])

Содержимое файла после двух запусков:

name,age
Kevin,28
Alice,23
Joe,34
Tima,31

Чтение через csv.reader

Объект csv.reader(file) перебирается циклом for и на каждом шаге отдает строку файла в виде списка строк. Строку заголовков удобно пропустить вызовом next(reader) до начала цикла.

import csv

with open("friends.csv", newline="", encoding="utf-8") as file:
    reader = csv.reader(file)
    header = next(reader)  # ['name', 'age']
    for name, age in reader:
        print(name, "-", int(age))

# Kevin - 28
# Alice - 23
# Joe - 34
# Tima - 31

Все значения читаются как str, даже если в файле записаны числа. Поэтому возраст в примере приводится к int вручную. Если строка в файле пустая, reader вернет пустой список, и распаковка в две переменные упадет с ValueError, такие строки стоит пропускать проверкой if not row: continue.

Reader читает файл построчно и не загружает его в память целиком, так что подходит и для таблиц на миллионы строк. Если нужен весь файл сразу, используйте rows = list(reader).

Словари: DictWriter и DictReader

Обращаться к столбцам по номеру неудобно: при добавлении нового столбца индексы сдвигаются. Классы DictWriter и DictReader работают со словарями, где ключами служат названия столбцов.

import csv

users = [
    {"name": "Tom", "age": 28},
    {"name": "Alice", "age": 23},
]

with open("users.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(file, fieldnames=["name", "age"])
    writer.writeheader()
    writer.writerows(users)
    writer.writerow({"name": "Sam", "age": 41})

Параметр fieldnames обязателен и задает порядок столбцов. Метод writeheader() записывает строку заголовков. Если в словаре есть ключ, которого нет в fieldnames, будет ValueError. Лишние ключи можно отбросить параметром extrasaction="ignore", а для отсутствующих ключей задать значение по умолчанию через restval.

with open("users.csv", newline="", encoding="utf-8") as file:
    for row in csv.DictReader(file):
        print(row["name"], row["age"])

# Tom 28
# Alice 23
# Sam 41

DictReader берет названия столбцов из первой строки файла. Если заголовков в файле нет, передайте их сами: csv.DictReader(file, fieldnames=["name", "age"]). Список словарей легко сохранить и в другие форматы, например в JSON.

Разделитель, кавычки и кодировка для Excel

Русская версия Excel по умолчанию ждет в CSV точку с запятой, потому что запятая там служит десятичным разделителем. Файл с запятыми он откроет одной колонкой. Разделитель задается параметром delimiter и у writer, и у reader.

import csv
rows = [["товар", "цена"], ["чай", "120,50"], ["сыр", "480,00"]]
with open("price.csv", "w", newline="", encoding="utf-8-sig") as file:
    csv.writer(file, delimiter=";").writerows(rows)

Кодировка utf-8-sig добавляет в начало файла метку BOM, по которой Excel понимает, что текст в UTF-8, и показывает кириллицу без кракозябр. Файлы, сохраненные из старого Excel, часто приходят в cp1251, их нужно открывать именно с этой кодировкой, иначе будет UnicodeDecodeError.

ПараметрПо умолчаниюНазначение
delimiter","Символ-разделитель полей
quotechar'"'Символ для кавычек
quotingcsv.QUOTE_MINIMALКогда брать значения в кавычки
lineterminator"\r\n"Конец строки при записи
skipinitialspaceFalseИгнорировать пробел после разделителя

Если разделитель заранее неизвестен, его можно определить классом csv.Sniffer: метод sniff() анализирует фрагмент текста и возвращает подходящий диалект. Полное описание параметров есть в документации модуля csv.

Когда лучше взять pandas

Модуль csv хорош для построчной обработки, конвертации и простых отчетов без внешних зависимостей. Когда нужно фильтровать, группировать, считать суммы по столбцам или объединять несколько таблиц, удобнее библиотека Pandas: pd.read_csv() загружает файл в DataFrame и сам определяет типы столбцов.

КритерийМодуль csvpandas
УстановкаНе нужнаpip install pandas
Типы данныхВсе строкиЧисла и даты распознаются
ПамятьПострочно, малоВся таблица в памяти
АнализВручную в циклеГотовые методы

Частые вопросы

Короткие ответы на типичные проблемы при работе с CSV.

Почему в CSV появляются пустые строки между записями?

Файл открыт без newline="". На Windows текстовый режим заменяет \n на \r\n, и вместе с \r\n от writer получается лишний перевод строки. Добавьте newline="" в вызов open().

Как прочитать только один столбец?

С DictReader достаточно генератора: names = [row["name"] for row in csv.DictReader(file)]. С обычным reader берут элемент по индексу, предварительно пропустив заголовок.

Как записать в CSV числа с запятой в дробной части?

Модуль csv пишет float с точкой, как str(3.5). Для русского Excel преобразуйте число в строку с заменой: str(price).replace(".", ","), а разделителем полей сделайте точку с запятой.

Можно ли изменить строку прямо в CSV файле?

Нет, текстовый файл нельзя править по месту. Прочитайте все строки в список, измените нужные и перезапишите файл целиком в режиме "w".