2025, Dec 17 03:00
Fixing AttributeError: 'list' object has no attribute 'items' in Python JSON parsing
Fix Python AttributeError: 'list' object has no attribute 'items' when parsing JSON. Learn to iterate lists and dicts correctly using get() and type checks.
Parsing JSON is straightforward until the data shape isn’t what your loop expects. A common pitfall is treating a list like a dict. Here’s a compact case: trying to enumerate dictionary items from a JSON file and immediately hitting AttributeError: 'list' object has no attribute 'items'.
Data shape
The JSON file contains a key that maps to a list with a single dictionary inside. That difference—list versus dict—drives the error.
{
"offer": [
{"bleach": 14 ,
"tshirt": 25,
"notebook": 6,
"mayo": 3,
"kiwi": 11,
"perfume": 68,
"hat": 2,
"toy": 17}
]
}
Problematic code
The following snippet assumes the value behind the key is a dictionary and tries to call items() directly. The logic is intact, but the container type isn’t.
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} $")
Why the error happens
The key offer points to a list, not a dictionary. Lists don’t implement items(), so calling items() raises AttributeError. To access key–value pairs, you must first iterate the list, then operate on each dictionary it contains.
Correct approach
Iterate the list under offer, make sure each element is a dict, and then enumerate its items. This preserves the flow and makes the container types explicit.
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}")
Why it matters
In JSON parsing, structure dictates control flow. If a key maps to a list, you iterate it. If it maps to a dictionary, you use items(). Mixing those up leads to runtime errors that are easy to overlook. Using a safe lookup like get with a default value helps prevent KeyError if the key is absent. A simple type check clarifies expectations and makes the loop robust when the data is exactly what you think it is.
Takeaways
Before writing loops, verify whether a node in the JSON tree is a list or a dictionary and structure your iteration accordingly. Iterate lists first, then drill into dict items when appropriate. Small safeguards—like a default from get and an explicit type check—save time and make the intent of your code unambiguous.