← назад к разделу

Одна переменная держит одно значение. Ответ сервиса — не одно значение, а набор: номер заказа, сумма, статус, а рядом перечень позиций. Для наборов в языке есть два хранилища, и почти вся работа с данными — работа с ними.

список — по номеру, с нуля NEW[0] PAID[1] SHIPPED[2] словарь — по имени поля "id": "ord-042" "status": "PAID" "total": 4990 разобранный JSON и есть словарь ответ["items"][0]["product"]каждая скобка — шаг вглубь поля может не быть — тогда get(), а не [ ]

Список хранит по порядку и достаётся номером; словарь — по имени поля. Ответ сервиса — словарь со списками внутри.

Обязательно

Список: перечень по порядкуспросят на собеседовании

Список — это значения по порядку, в квадратных скобках через запятую. Достают их по номеру, и нумерация идёт с нуля — это главная ловушка новичка:

живой пример

статусы = ["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] каждый второй; кортеж это неизменяемый список, множество хранит уникальные значения, и разность множеств показывает, чего нет.

Что почитать дальше

  • Циклы — пройти по всем позициям, а не только по первой.
  • Условия — сравнить полученное значение с ожидаемым.
  • Функции — собрать чтение полей в одном месте.
  • Разбор данных — посчитать по выгрузке и найти расхождение.