Работа с 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 по умолчанию), но нужно помнить, что это может привести к проблемам с преобразованием в программах, написанных на других языках программирования.
