2026, Jan 08 21:02

Как исправить AttributeError: 'list' object has no attribute 'items' при разборе JSON в Python

Почему возникает AttributeError: 'list' object has no attribute 'items' при работе с JSON в Python и как правильно итерировать список под ключом и пары словаря.

Разбирать JSON просто, пока форма данных соответствует ожиданиям вашего цикла. Частая ошибка — принимать список за словарь. Вот короткий пример: вы пытаетесь перебирать пары ключ–значение из JSON‑файла и сразу получаете AttributeError: 'list' object has no attribute 'items'.

Структура данных

В JSON‑файле есть ключ, который указывает на список, внутри которого лежит один словарь. Именно это различие — список вместо словаря — и вызывает ошибку.

{
"offer": [
{"bleach": 14 ,
"tshirt": 25,
"notebook": 6,
"mayo": 3,
"kiwi": 11,
"perfume": 68,
"hat": 2,
"toy": 17}
]
}

Проблемный код

Этот фрагмент считает, что по ключу лежит словарь, и сразу вызывает items(). Логика верная, но тип контейнера — нет.

import json
with open("offers.json", "r") as fh:
offers_block = json.load(fh)["offer"]

for idx, (k, v) in enumerate(offers_block.items()):
print(f"{str(idx + 1)} {k} {v:02} $")

Почему возникает ошибка

Ключ offer ссылается на список, а не на словарь. У списков нет метода items(), поэтому его вызов приводит к AttributeError. Чтобы получить пары ключ–значение, сначала пройдитесь по списку, а затем работайте с каждым словарём внутри.

Правильный подход

Итерируйте список под offer, убедитесь, что каждый элемент — словарь, и затем перечисляйте его пары. Так сохраняется логика и явно задаются типы контейнеров.

import json

with open("offers.json") as fp:
payload = json.load(fp)

for entry in payload.get("offer", []):
assert isinstance(entry, dict)
for n, (name, amount) in enumerate(entry.items(), 1):
print(f"{n} {name} ${amount}")

Почему это важно

При разборе JSON структура определяет логику обхода. Если по ключу лежит список — его нужно итерировать. Если словарь — работать через items(). Путаница между ними приводит к ошибкам выполнения, которые легко упустить. Безопасный доступ через get со значением по умолчанию помогает избежать KeyError, если ключа нет. Простая проверка типа проясняет ожидания и делает цикл надёжным, когда данные именно такие, какими вы их считаете.

Выводы

Прежде чем писать циклы, проверьте, является ли узел в JSON‑дереве списком или словарём, и стройте обход соответственно. Сначала проходите списки, затем при необходимости переходите к элементам словаря через items(). Небольшие страховки — значение по умолчанию в get и явная проверка типа — экономят время и делают намерения кода однозначными.