Python csv модуль: практические примеры для табличных данных
Модуль csv в Python предоставляет инструменты для работы с файлами формата CSV (Comma-Separated Values). Этот формат широко используется для хранения табличных данных: каждая строка соответствует одной записи, а колонки разделены определённым символом (обычно запятой). Модуль позволяет гибко настраивать разделители, кавычки и правила экранирования, что делает его незаменимым при обработке данных из различных источников.
Основные приёмы работы с модулем csv
Как прочитать CSV файл с заголовками и получить доступ к данным по имени колонки?
Наиболее эффективным решением является использование класса DictReader. Он автоматически считывает первую строку как заголовки и возвращает каждую последующую строку в виде словаря, где ключи – имена колонок. Это упрощает доступ к данным и делает код читаемым.
import csv
with open('employees.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['Name']}: {row['Salary']}")модуль csv в python (модуль csv в python)
Иван: 50000 Мария: 60000
Пример структуры файла employees.csv:
Name,Position,Salary
Иван,Разработчик,50000
Мария,Аналитик,60000
Пояснение: после открытия файла создаётся экземпляр csv.DictReader, который итерируется по строкам. Каждая строка – словарь, ключи которого – значения из первой строки файла. Доступ к полям осуществляется по имени, что удобно при изменении порядка колонок.
Как прочитать CSV файл без заголовков и обращаться к колонкам по индексу?
Для файлов, не содержащих строку заголовков, используется csv.reader. Он возвращает каждую строку как список значений. Порядок колонок фиксирован, и доступ к ним выполняется по индексу.
import csv
with open('data_no_header.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row[0], row[1]) # первая и вторая колонки
Товар1 100 Товар2 200
Этот вариант подходит, когда структура колонок известна заранее и не планируется менять. Однако при изменении порядка колонок код придётся править.
Типичная ошибка: если в файле используется нестандартный разделитель (например, точка с запятой), по умолчанию csv.reader ожидает запятую. Решение – указать параметр delimiter:
reader = csv.reader(f, delimiter=';')
Аналогично для DictReader. Также возможна ошибка кодировки – необходимо явно задать encoding.
Как записать данные в CSV файл?
Для записи применяются классы csv.writer и csv.DictWriter. Первый ожидает списки, второй – словари.
import csv
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Name', 'Age']) # заголовок
writer.writerow(['Анна', 28])
writer.writerow(['Пётр', 35])
Результат – файл output.csv с двумя строками данных. Параметр newline='' предотвращает добавление лишних пустых строк в Windows.
Для DictWriter необходимо передать список имён полей (fieldnames):
with open('employees_out.csv', 'w', encoding='utf-8', newline='') as f:
fieldnames = ['Name', 'Position', 'Salary']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'Name': 'Ольга', 'Position': 'Менеджер', 'Salary': 55000})
Как обработать CSV данные, не сохраняя их в файл (работа со строками)?
Иногда данные поступают в виде строки (например, из веб-запроса). Для таких случаев применяется io.StringIO (или io.BytesIO для бинарных данных).
import csv
import io
csv_data = "Name,Age\nИван,30\nМария,25"
f = io.StringIO(csv_data)
reader = csv.DictReader(f)
for row in reader:
print(row['Name'], row['Age'])
Иван 30 Мария 25
Этот способ удобен для тестирования или обработки данных, полученных через API.
Как настроить диалект CSV (правила цитирования, разделители)?
Модуль поддерживает предопределённые диалекты (excel, excel-tab, unix) и позволяет создавать собственные с помощью csv.register_dialect.
import csv
csv.register_dialect('mydialect', delimiter='|', quoting=csv.QUOTE_ALL)
with open('pipe_separated.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f, dialect='mydialect')
for row in reader:
print(row)
Здесь определён диалект с разделителем | и обязательным цитированием всех полей. Это полезно, если формат файла отличается от стандартного.
Типичная ошибка: неправильное указание диалекта может привести к некорректному разбору. Особенно внимательно следует настраивать quotechar (символ кавычки) и escapechar.
Как автоматически определить диалект CSV файла?
Класс csv.Sniffer анализирует образец данных и определяет разделитель, символ кавычек и другие параметры. Это избавляет от ручной настройки при обработке файлов из разных источников.
import csv
with open('unknown.csv', 'r', encoding='utf-8') as f:
sample = f.read(1024) # читаем начало файла
dialect = csv.Sniffer().sniff(sample)
f.seek(0)
reader = csv.reader(f, dialect=dialect)
for row in reader:
print(row)
Sniffer требует достаточно представительного образца. Если файл короткий, может потребоваться увеличить размер образца.
Как обрабатывать большие CSV файлы, не загружая их целиком в память?
Модуль csv поддерживает итеративный подход: чтение строк по одной. Это позволяет обрабатывать файлы любого размера без переполнения памяти.
import csv
with open('large_data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
next(reader) # пропустить заголовок
for row in reader:
# обработка строки
process(row)
Аналогично для DictReader. Такой подход эффективен для ETL-процессов и пакетной обработки.
Как обработать строки с пропущенными значениями?
Если в некоторых строках отсутствуют отдельные поля, модуль csv по умолчанию оставляет их пустыми строками. Для DictReader пропущенные поля не включаются в словарь. Чтобы установить значение по умолчанию, можно использовать параметр restval.
import csv
with open('missing.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f, restval='N/A')
for row in reader:
print(row)
Если же файл содержит разное количество полей в строках, поможет csv.reader с проверкой длины списка.
Расширенные примеры использования модуля csv
Пример 1: Чтение CSV с несколькими разделителями и разными типами цитирования
Предположим, файл использует табуляцию как разделитель, а некоторые поля заключены в двойные кавычки. Для работы используется диалект excel-tab.
import csv
with open('tab_separated.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f, dialect='excel-tab')
for row in reader:
print(row)
['ID', 'Name', 'Description'] ['1', 'Item A', 'Simple item'] ['2', 'Item B', 'Complex "description" with quotes']
Обратите внимание: кавычки внутри цитируемого поля экранируются автоматически.
Пример 2: Запись CSV с пользовательским диалектом и нестандартным символом кавычек
Создаётся собственный диалект с апострофом в качестве символа цитирования и разделителем двоеточие.
import csv
csv.register_dialect('colon', delimiter=':', quotechar="'", quoting=csv.QUOTE_ALL)
with open('custom.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f, dialect='colon')
writer.writerow(['a', 'b', 'c'])
writer.writerow([1, 2, 3])
Результат в файле custom.csv:
'a':'b':'c' '1':'2':'3'
Пример 3: Использование Sniffer для автоматического определения диалекта и разделителя
Функция csv.Sniffer().sniff() возвращает объект диалекта. Дополнительно можно проверить, содержит ли файл заголовок.
import csv
with open('mixed.csv', 'r', encoding='utf-8') as f:
sample = f.read(2048)
dialect = csv.Sniffer().sniff(sample)
has_header = csv.Sniffer().has_header(sample)
f.seek(0)
reader = csv.reader(f, dialect=dialect)
if has_header:
header = next(reader)
print('Заголовок:', header)
for row in reader:
print(row)
Заголовок: ['Дата', 'Продажи', 'Комментарий'] ['2024-01-01', '100', 'хороший месяц'] ['2024-02-01', '150', 'отлично']
Этот пример демонстрирует, как автоматически адаптироваться к различным форматам без ручной настройки.
Пример 4: Обработка CSV с вложенными данными (например, списки внутри поля)
Если одно поле содержит список значений, разделённых точкой с запятой, их можно дополнительно разбить после чтения.
import csv
with open('nested.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
tags = row['Tags'].split(';')
print(f"Title: {row['Title']}, Tags: {tags}")
Title: Статья 1, Tags: ['python', 'csv'] Title: Статья 2, Tags: ['data', 'analysis']
Пример 5: Работа с кодировками и большими файлами (построчное чтение с фильтрацией)
При обработке больших файлов важно не накапливать данные в памяти. Ниже показано, как фильтровать строки по условию и записывать результат в новый файл.
import csv
with open('big_data.csv', 'r', encoding='utf-8') as inf, open('filtered.csv', 'w', encoding='utf-8', newline='') as outf:
reader = csv.DictReader(inf)
writer = csv.DictWriter(outf, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
if int(row['Age']) >= 18:
writer.writerow(row)
Этот код копирует только строки, где возраст не меньше 18, эффективно используя память.
Пример 6: Использование csv.reader со специальными параметрами (escapechar, lineterminator)
Если в данных встречаются символы, совпадающие с разделителем, их можно экранировать обратным слешем.
import csv
with open('escaped.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f, escapechar='\\', quoting=csv.QUOTE_NONE)
for row in reader:
print(row)
['a', 'b, c', 'd'] ['1', '2', '3']
Здесь запятая внутри поля не считается разделителем, так как перед ней стоит \\. Параметр quoting=csv.QUOTE_NONE отключает цитирование.