Одна переменная держит одно значение. Ответ сервиса — не одно значение, а набор: номер заказа, сумма, статус, а рядом перечень позиций. Для наборов в языке есть два хранилища, и почти вся работа с данными — работа с ними.
Список хранит по порядку и достаётся номером; словарь — по имени поля. Ответ сервиса — словарь со списками внутри.
Список: перечень по порядкуспросят на собеседовании
Список — это значения по порядку, в квадратных скобках через запятую. Достают их по номеру, и нумерация идёт с нуля — это главная ловушка новичка:
живой пример
статусы = ["NEW", "PAID", "SHIPPED"]
print(статусы[0]) # NEW — первый, а не нулевой
print(статусы[-1]) # SHIPPED — последний, счёт с конца
print(len(статусы)) # 3 — сколько всего
print("PAID" in статусы) # True — есть ли такой
статусы.append("DELIVERED") # добавили в конец
print(статусы)
Запустить
Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →
Если попросить элемент, которого нет, программа упадёт с
IndexError: list index out of range. Ошибка полезная: значит, значений пришло
меньше, чем вы ожидали.
Отработать здесь: Собрать список · Взять элемент по номеру · Добавить элемент в список
Словарь: значение по имениспросят на собеседовании
Когда у каждого значения своё имя, номер не поможет — нужен словарь. Фигурные скобки, пары «ключ: значение», доступ по ключу:
живой пример
заказ = {"id": "ord-042", "status": "PAID", "total": 4990}
print(заказ["status"]) # PAID — достаём по имени поля
заказ["status"] = "SHIPPED" # поменяли значение
заказ["paid_at"] = "2026-09-12" # добавили поле, которого не было
print(заказ)
Запустить
Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →
Это и есть JSON. Ответ сервиса в формате JSON после разбора превращается в
словарь один в один: те же ключи, те же значения. Поэтому «прочитать поле из
ответа» — это ответ["status"], и ничего больше.
Отработать здесь: Достать значение по ключу
Поле, которого может не быть
Вот здесь ломается больше всего проверок. Обращение к отсутствующему ключу — это не пустое значение, а ошибка.
Так не надо
живой пример
# ошибка: поля «скидка» в заказе нет, и обращение по ключу роняет программу
заказ = {"id": "ord-042", "status": "PAID", "total": 4990}
print(заказ["скидка"]) # KeyError: 'скидка'
Запустить
Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →
Так надо
живой пример
заказ = {"id": "ord-042", "status": "PAID", "total": 4990}
print(заказ.get("скидка")) # None, если поля нет
print(заказ.get("скидка", 0)) # 0 — своё значение вместо None
if "скидка" in заказ: # когда важно именно наличие поля
print(заказ["скидка"])
else:
print("поля «скидка» нет")
Запустить
Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →
Разница в одной фразе: квадратные скобки требуют, чтобы поле было, а get()
допускает, что его нет. Обратная сторона — get() прячет пропажу: если поле
обязано приходить всегда, проверяйте его через in, иначе проверка промолчит о
настоящей поломке.
Отработать здесь: Проверить, есть ли поле · Поле, которого может не быть
Вложенность: словари внутри списков внутри словарей
Настоящий ответ — словарь, внутри которого лежат другие словари и списки. Читают его по шагам слева направо: каждая скобка — шаг вглубь.
живой пример
ответ = {
"id": "ord-042",
"customer": {"id": "cus-01", "name": "Анна"},
"items": [
{"product": "Кофемолка", "qty": 1, "price": 4990},
{"product": "Ланчбокс", "qty": 2, "price": 890},
],
"total": 6770,
}
print(ответ["customer"]["name"]) # Анна
print(ответ["items"][0]["product"]) # Кофемолка — первая позиция
print(len(ответ["items"])) # 2 — сколько позиций
покупатель = ответ["customer"] # запутались — разложите по шагам
print(покупатель["name"])
Запустить
Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →
Одна длинная цепочка короче, но когда она упадёт, по сообщению не понять, на каком шаге. Разложенная по переменным — понятно сразу.
Отработать здесь: Разобрать вложенный ответ
Чем список отличается от словаряспросят на собеседовании
Правило простое: список — когда элементы однотипные и важен порядок (позиции
заказа, найденные записи); словарь — когда у каждого значения своё имя (поля
объекта). В ответе сервиса они почти всегда вместе: сам ответ — словарь, а
items внутри него — список словарей.
Глубже: срезы, кортеж и множестворасширенноеспросят на собеседовании
Из списка часто нужен не один элемент, а кусок. Срез items[1:3] даёт элементы с первого по второй, конец не входит; items[-1] последний элемент, items[::2] каждый второй, items[::-1] список задом наперёд. Срез всегда возвращает новый список и не портит старый.
Кортеж это список, который нельзя менять: point = (10, 20). Его берут для пары или тройки значений, которые не должны случайно измениться, и как ключ словаря, чем список быть не может. Множество хранит только уникальные значения и не помнит порядок: set([1, 2, 2, 3]) даёт {1, 2, 3}. Проверка «есть ли в множестве» мгновенная даже на миллионе значений, а вычитание множеств показывает, чего не хватает.
живой пример
ids_expected = {101, 102, 103}
ids_actual = {101, 103, 104}
print(sorted(ids_expected - ids_actual)) # [102] — пропало
print(sorted(ids_actual - ids_expected)) # [104] — лишнее
orders = [{"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}]
print(orders[-1]["id"], [o["id"] for o in orders[::2]]) # 4 [1, 3]
Запустить
Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →
Умножить все числа в списке на три нельзя через prices * 3: это повторит список трижды. Пишут [p * 3 for p in prices], а длину любой коллекции даёт len.
Коротко
- Список — перечень по порядку, нумерация с нуля,
[-1]— последний. - Словарь — «имя: значение»; разобранный JSON и есть словарь, поэтому чтение поля
из ответа выглядит как
ответ["status"]. - Отсутствующий ключ роняет программу с
KeyError; безопасно —get(). - Поле, которое обязано приходить всегда, проверяйте через
in:get()прячет пропажу и оставляет проверку зелёной. - Вложенность читается по шагам:
ответ["items"][0]["product"]. - Срез
items[1:3],items[-1]последний,items[::2]каждый второй; кортеж это неизменяемый список, множество хранит уникальные значения, и разность множеств показывает, чего нет.
Что почитать дальше
- Циклы — пройти по всем позициям, а не только по первой.
- Условия — сравнить полученное значение с ожидаемым.
- Функции — собрать чтение полей в одном месте.
- Разбор данных — посчитать по выгрузке и найти расхождение.