Работа с csv и json файлами в Python
Управление текстовыми файлами формата csv, tsv, dtv, json
в языке программирования Python
Формат CSV
CSV (от англ. Comma-Separated Values — значения, разделённые запятыми) — текстовый формат, предназначенный для представления табличных данных. Строка таблицы соответствует строке текста, которая содержит одно или несколько полей, разделенных запятыми.
К примеру, следующая таблица:
Rank | Language | Share |
---|---|---|
1 | Python | 31.17% |
2 | Java | 17.75% |
3 | JavaScript | 8% |
4 | C# | 7.05% |
5 | PHP | 6.09% |
в формате csv
будет выглядеть следующим образом:
|
|
Подобные файлы можно обрабатывать вручную подобно txt
— считывать, разделять на строки и отдельные элементы по разделителям с помощью split()
, но в Python есть отдельный модуль для работы с файлами формата dsv
.
dsv
(англ. delimiter separated values — «значения, разграниченные разделителем») общий формат для форм csv
, tsv
(англ. tab separated values — «значения, разделенные табуляцией») и других.Модуль csv
Для использования: import csv
В данном модуле есть два основных объекта: reader
и writer
, созданные, чтобы читать и создавать csv
файлы соответственно.
Чтение через reader
Рассмотрим файл products.csv
, содержащий информацию о товарах интернет магазина:
|
|
Код ниже читает содержимое файла и выводит его построчно:
|
|
|
|
Объект reader
дает доступ к построчному итератору, полностью аналогичному работе с файлом или списком.
После выполнения строки rows = csv.reader(file)
в переменную rows
будет записан итератор, с помощью которого можно «пробежаться» циклом по файлу. В каждой итерации цикла при этом будет доступна соответствующая строка файла, уже разбитая по запятым и представляющая собой список. При этом автоматически будут учтены все нюансы с запятыми внутри кавычек и самими кавычками.
При создании reader
объекта можно указать:
- аргумент
delimiter
— односимвольная строка, используемая для разделения полей, по умолчанию имеет значение','
- аргумент
quotechar
— односимвольная строка, используемая для кавычек в полях, содержащих специальные символы, по умолчанию имеет значение'"'
.
Чтение через DictReader
В модуле csv
есть специальный объект DictReader
, который поддерживает создание объекта-словаря на основе названий столбцов. С помощью DictReader
объекта можно обращаться к полям не по индексу, а по названию, что делает код более понятным.
Немного поменяем содержимое файла products.csv
. Теперь разделителем будет точка с запятой, также заключим текст с запятыми в кавычки во избежание ошибок при разделении строки на элементы:
|
|
Теперь прочитаем этот файл, используя DictReader
:
|
|
|
|
При создании DictReader
объекта значениями по умолчанию для аргументов delimiter
и quotechar
являются ','
(символ запятой) и '"'
(символ двойной кавычки) соответственно.
fieldnames
объекта DictReader
Запись через writer
Для записи данных в csv
файл можно использовать специальный writer
объект:
|
|
|
|
При открытии файла функцией open()
был использован параметр newline
со значением ''
(пустая строка), который отвечает за переводы строк при чтении или записи в текстовый файл. По умолчанию имеет значение None
, в этом случае все разделители строк преобразуются в '\n'
. Если в файле оказывается лишний перевод строки, то следует использовать этот параметр в режиме newline=''
, тогда '\n'
будет преобразован в пустую строку.
При создании writer
объекта так же можно его настраивать, задавая delimiter
и многие другие параметры.
|
|
|
|
Значение аргумента quoting=csv.QUOTE_NONNUMERIC
означает, что в кавычки будут браться все нечисловые значения. По умолчанию символом кавычки является "
, если нужно поменять символ, используется уже знакомый нам именованный аргумент quotechar
.
Для quoting
существуют и другие константы из модуля csv
:
QUOTE_ALL
: указывает объектам записи указывать все поляQUOTE_MINIMAL
: указывает объектам записи заключать в кавычки только те поля, которые содержат специальные символы, такие как разделительdelimiter
, кавычкаquotechar
или любой из символов вlineterminator
QUOTE_NONNUMERIC
: указывает объектам записи указывать все нечисловые поляQUOTE_NONE
: указывает объектам записи никогда не заключать в кавычки поля
Помимо метода writerow()
можно использовать и метод writerows()
, чтобы записать сразу несколько строк. Единственным аргументом этого метода может быть коллекция коллекций. То есть, каждый элемент списка rows
в нашем случае должен быть коллекцией. Если rows
будет, например, списком чисел, программа завершится с ошибкой.
Запись через DictWriter
Для записи данных в csv
файл также можно использовать DictWriter
объект, который позволяет записывать содержимое словаря в файл.
|
|
|
|
fieldnames
, иначе будет возникать ошибка ValueError
.Формат json
JSON (англ. JavaScript Object Notation, читается как “джЕйсон”) — текстовый формат обмена данными, основанный на синтаксисе объекта в языке программирования JavaScript. Как и многие другие текстовые форматы, JSON легко читается людьми. Несмотря на происхождение от JavaScript, формат считается независимым от языка и может использоваться практически с любым языком программирования.
В отличие от формата csv
, данные в формате json
не просто разделены запятыми, а чаще всего имеют структуру ключ-значение. Это напоминает словарь Python, но в отличие от словаря, ключи в json
могут быть только строками, заключенными в двойные кавычки:
|
|
Преимущества, которые сделали этот формат популярным:
- не занимает много места, является компактным в написании и быстро компилируется
- создание текстового содержимого понятно человеку, просто в реализации, а чтение со стороны среды разработки не вызывает никаких проблем. Чтение может осуществляться и человеком, поскольку ничего сложного в представлении данных нет
- структура преобразуется для чтения на любых языках программирования
- практически все языки имеют соответствующие библиотеки или другие инструменты для чтения данных JSON
В качестве значений в JSON могут быть использованы:
- число (целое или вещественное);
- литералы
true
(истина),false
(ложь),null
(отсутствие значения); - строка (последовательность символов, заключенная в двойные кавычки);
- список (заключается в квадратные скобки
[ ]
, значения разделяются запятыми). Список может быть пустым, значения в пределах одного списка могут иметь разный тип; - вложенный объект (неупорядоченное множество пар ключ: значение, заключённое в фигурные скобки
{ }
). Ключ описывается строкой, между ним и значением стоит символ:
. Пары ключ-значение отделяются друг от друга запятыми.
|
|
Также, переносы строк и отступы в формате json
необязательны. Они нужны только для удобства чтения.
|
|
Модуль json
Для использования: import json
Преобразование переменных программы (Python-объектов) в формат для хранения называется «сериализацией», а обратное преобразование — «десериализацией». В Python для сериализации и десериализации в формат json
есть одноимённый модуль.
Функция dumps()
Для сериализации данных в json
строку используется функция dumps()
из модуля json
. Для того, чтобы сериализовать данные с ее помощью, достаточно передать в нее аргументом любой сериализуемый Python-объект.
|
|
|
|
json
)Функция dump()
В отличие от функции dumps()
, которая сериализует Python-объект в json
строку, функция dump()
записывает переданный Python-объект в файл.
|
|
|
|
json
, например число, список, строку и т.дindent
, sort_keys
и separators
Функции записи dumps()
и dump()
имеют необязательные аргументы indent
, sort_keys
и separators
, которые можно использовать для более удобного чтения человеком.
Аргумент
indent
задает отступ от левого края. По умолчанию имеет значениеNone
для более компактного представления без отступов. Если значениемindent
является строка, то она используется в качестве отступа.Аргумент
sort_keys
задает сортировку ключей в результирующемjson
. По умолчанию имеет значениеFalse
для более быстрого выполнения. Если установить значение аргумента вTrue
, то ключи будут отсортированы в алфавитном порядке, что особенно удобно, когда ключей много.Аргумент
separators
задает кортеж, состоящий из двух элементов(item_separator, key_separator)
, которые представляют разделители для элементов и ключей. По умолчанию аргумент имеет значение(', ', ': ')
.
|
|
|
|
Функция loads()
Для десериализации данных нужно использовать функцию loads()
. Ее аргумент — это строка с данными в формате json
.
|
|
|
|
json
не сможет правильно прочитать такую строку, и программа завершится с ошибкой json.decoder.JSONDecodeError
Функция load()
В отличие от функции loads()
, которая в качестве аргумента принимает строку с данными в формате json
, функция load()
принимает файловый объект и возвращает его десериализованное содержимое.
Пусть файл data.json
имеет следующее содержимое:
|
|
Тогда следующий код преобразует data.json
в словарь data
и выведет его элементы:
|
|
|
|
Типы данных в json
Модуль json
автоматически определяет тип значения при десериализации. Такая автоматическая работа с типами данных выгодно отличает json
от csv
, при работе с которым таких автоматических преобразований нет.
Важно также понимать, что при преобразовании данных в формат JSON, данные не всегда будут того же типа, что исходные данные в Python. Например, кортежи при записи в JSON превращаются в списки. Так происходит из-за того, что в JSON используются другие типы данных, и не для всех типов данных Python есть соответствия.
Таблица конвертации типов данных Python в JSON:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float | number |
True | true |
False | false |
None | null |
Таблица конвертации JSON в типы данных Python:
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number (int) | int |
number (real) | float |
true | True |
false | False |
null | None |
Ограничение по типам данных
В формат JSON нельзя записать словарь, у которого ключи – кортежи. Поэтому есть необязательный аргумент skipkeys
, который игнорирует элементы с подобными ключами:
|
|
|
|
None
, то ошибки не будет, вместо этого они будут преобразованы в строки.Кириллические символы в json
Вывод следующего кода может вызвать смущение:
|
|
|
|
Каждая буква из строк Иван
и Иванов
будет заменена на её код. Эти коды стандартны, и код для каждой из букв индивидуален. Например 0438
— код буквы и
. Обратное преобразование из строки в словарь вернет закодированное значение в первоначальный вид.
С помощью необязательного аргумента ensure_ascii
функций dumps()
и dump()
можно отказаться от такого кодирования:
|
|
|
|
Python преобразует такую строку обратно в словарь без проблем (поскольку использует Unicode по умолчанию), но нужно помнить, что это может привести к проблемам с преобразованием в программах, написанных на других языках программирования.
