Why do you have to call .items when iterating over a dictionary in Python?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When you iterate directly over a Python dictionary, you get keys by design, not key-value pairs. This surprises newcomers, especially if they expect map iteration to return both parts automatically. Calling .items() is the explicit way to request key-value tuples and is usually the clearest pattern when both are needed.
What Direct Dictionary Iteration Returns
Default dictionary iteration yields keys:
This is equivalent to iterating data.keys():
The design aligns with dictionary semantics where keys define identity and lookup behavior.
Why Python Is Key-Centric Here
Dictionary membership checks are key-based:
Since in and default iteration both operate on keys, the model remains consistent across operations. This consistency is one reason Python chose key iteration as the default behavior.
Use .items() for Key-Value Pairs
When you need both key and value, call .items() and unpack tuples:
This avoids extra lookups and communicates intent clearly.
Compare with a less ideal pattern:
This still works, but .items() is usually clearer and may avoid repeated dictionary indexing overhead.
Dictionary Views and Their Behavior
keys(), values(), and items() return dynamic view objects, not copied lists.
The view reflects current dictionary contents. If you need a fixed snapshot for later processing, convert with list(d.items()).
Mutation While Iterating
Changing dictionary size during iteration can raise runtime errors. If you plan to add or remove keys, iterate over a snapshot:
This avoids mutation during live iteration on the same view.
Choosing the Right Iteration Method
Use the method that matches your intent:
- '
for key in dord.keys()when only keys are needed,' - '
d.values()when only values are needed,' - '
d.items()when both key and value are needed.'
Example value-only sum:
Intent-focused iteration makes code easier for teams to read and review.
Performance and Readability Notes
For most codebases, readability matters more than tiny micro-optimizations. Still, .items() is typically efficient and avoids repeated hash table lookups for each key.
Simple benchmark pattern:
Both are valid. Prefer the style that directly expresses what the loop consumes.
Version Context and Historical Notes
In Python 3, dictionary views are lazy and dynamic. Older Python 2 APIs had separate iterator methods that behaved differently, which can cause confusion when reading legacy tutorials. In modern Python, .items() is the idiomatic, forward-compatible way to iterate pairs.
Common Pitfalls
- Expecting
for x in dto yield key-value tuples instead of keys. - Iterating keys and repeatedly indexing values when
.items()would be clearer. - Converting views to lists unnecessarily and increasing memory usage.
- Modifying dictionary size during live iteration without creating a snapshot.
- Using vague variable names that hide whether loop variables represent keys or tuples.
Summary
- Direct dictionary iteration returns keys by intentional language design.
- Use
.items()to iterate key-value pairs cleanly. - Dictionary view objects are dynamic, not static snapshots.
- Choose
keys,values, oritemsbased on loop intent. - Prefer readable pair iteration with tuple unpacking in team code.

