Аббревиатура JSON
расшифровывается как JavaScript Object Notation
или, в вольном переводе, система обозначения (или записи) объектов JavaScript.
Несмотря на то, что JSON
является подмножеством языка программирования JavaScript, сейчас это общепризнанный формат обмена данными, и многие языки программирования, включая Python, содержат эффективные инструменты для работы с этим форматом.
Важно! Итак, JSON — это простой, структурированный, основанный на использовании текста формат обмена данными.
Когда мы говорим об обмене данными, то чаще всего имеем в виду передачу данных по компьютерным сетям, например пересылку данных от сервера к браузеру.
Для работы с данными в формате JSON
в Python используется библиотека json
, которую необходимо будет загрузить в начале работы. Также нам может быть полезен модуль pprint
(именно так, с двумя "р" в начале) и встроенная в него функция pprint
, с помощью которой можно красиво выводить на экран структурированные данные.
import json
from pprint import pprint
Информация в формате JSON
представляет собой (в закодированном виде) одну из двух структур:
Формат JSON допускает неограниченное количество вложений этих структур друг в друга.
Все упражнения будем выполнять на примере файла, содержащего информацию об ингредиентах блюд, относящихся к кухням разных народов.
Чтобы перевести данные из формата JSON
в формат, который можно обрабатывать на Python, необходимо выполнить процедуру, которая называется десериализация
(иными словами, декодирование данных). Обратный процесс, связанный с переводом структур данных Python в формат JSON
, называется сериализация
.
Для выполнения десериализации мы воспользуемся методом load
модуля json
. В качестве параметра укажем ссылку на файл:
with open('data/recipes.json') as f:
recipes = json.load(f)
Чтобы разобраться в структуре данных, давайте выведем их на экран с помощью функции pprint
. Будьте готовы к тому, что данных в наборе много, поэтому в ячейке появится несколько сот строк. Нам не нужно будет просматривать все строки. Главное — понять общую структуру объекта recipes
:
#pprint(recipes)
[{'cuisine': 'greek',
'id': 10259,
'ingredients': ['romaine lettuce',
'black olives',
'grape tomatoes',
'garlic',
'pepper',
'purple onion',
'seasoning',
'garbanzo beans',
'feta cheese crumbles']},
{'cuisine': 'southern_us',
'id': 25693,
'ingredients': ['plain flour',
'ground pepper',
'salt',
'tomatoes',
'ground black pepper',
'thyme',
'eggs',
'green tomatoes',
'yellow corn meal',
'milk',
'vegetable oil']},
Итак, мы видим, что рецепт каждого блюда описан в виде словаря, состоящего из трёх пар "ключ-значение". Ключ cuisine
обозначает принадлежность блюда к определённой кухне, id
— это уникальный идентификационный номер блюда, а ключ ingredients
содержит перечень продуктов, входящих в состав блюда.
После того как мы провели десериализацию данных из JSON-файла, мы можем работать с полученным объектом, как с обычным словарём, или, как в случае с нашими данными, списком. Единственное отличие этой работы от манипуляций с привычными нам списками и словарями заключается в том, что данных теперь больше и они помещены внутрь структуры с большим количеством уровней вложенности. Тем не менее общие приёмы работы остаются стандартными.
Давайте выясним некоторые детали о блюде, которое записано первым в списке. Например, чтобы узнать ID
этого блюда, мы можем использовать такой код:
recipes[0]['id']
10259
В данном случае сначала мы извлекаем из списка первый элемент (индекс 0). Поскольку каждый элемент списка является словарём, для получения нужной информации о конкретном блюде нам нужно указать ключ словаря. ID
блюда доступно по ключу 'id'
, и мы указываем этот ключ в отдельной паре квадратных скобок.
Для получения списка ингредиентов первого блюда в списке мы можем использовать тот же код, заменив в нём ключ 'id'
на 'ingredients'
:
recipes[0]['ingredients']
['romaine lettuce', 'black olives', 'grape tomatoes', 'garlic', 'pepper', 'purple onion', 'seasoning', 'garbanzo beans', 'feta cheese crumbles']
Ещё один пример касается извлечения информации о конкретном блюде. Давайте попробуем найти информацию о том, к какой кухне относится блюдо с id = 13121
. Сложность задачи заключается в том, что все id
хранятся в словарях, которые являются элементами списка. Для получения данных о нужном блюде нам придётся перебрать все элементы списка, проверить их id
, и при обнаружении совпадения извлечь нужную информацию:
for recipe in recipes: # начинаем перебор всех рецептов
if recipe['id'] == 13121: # если id текущего рецепта равен искомому
print(recipe['cuisine']) # выводим на экран кухню, к которой относится блюдо
break # и прерываем цикл, т.к. нужное блюдо уже найдено
thai
Теперь мы можем обращаться к словарю food по ключам и получать информацию о количестве рецептов, включающих тот или иной ингредиент: