Reference

Reference · Dictionaries

dict.items()

dict.items() returns a live view of a dictionary's (key, value) pairs — the cleanest way to iterate when your loop needs both the key and the value.

XCODXReference · Updated

Definition

dict.items() returns a view of the dictionary's (key, value) pairs. Each element is a two-item tuple — the key first, the value second — which makes it the method to reach for whenever a loop needs *both* halves of every entry. Unpack the tuple directly in the loop header (for key, value in d.items():) and you have both without a second lookup.

It completes the trio with dict.keys() and dict.values(): same underlying entries, same order (insertion order, guaranteed since Python 3.7), but yielding pairs instead of just keys or just values. When you only need one side, prefer the narrower method; when the work touches both the key and the value, items is the right starting point.

The pairing is what makes items special. Iterating keys alone forces a d[key] lookup every time you want the value; items hands you both at once, which is more convenient, slightly faster in a tight loop, and impossible to get wrong by mistyping the key. Whenever a loop, filter, or dict comprehension consumes both key and value, start from items.

Syntax

view = d.items()

# takes no arguments
# returns: a dict_items view of (key, value) tuples

Parameters

dict.items() takes no arguments. It is an instance method called on the dictionary itself as d.items(), and its declared signature is therefore empty — there is nothing to pass and nothing to configure.

ParameterRequiredDescription
*(none)*-items() accepts no parameters. Call it with empty parentheses on the dictionary you want to iterate.

Return value

A dict_items view object presenting the dictionary's (key, value) pairs. A view is not a list: it is a lightweight window onto the dictionary that is dynamic — if the dictionary changes after you call items(), the same view object reflects those changes. Convert it to a list when you need a fixed, indexable snapshot.

  • Pairs follow insertion order (guaranteed since Python 3.7).
  • Each value is the entry's value as-is (a reference, for lists and dicts).
  • The view is dynamic — later inserts and deletes are visible through it.
  • list(d.items()) copies the pairs into an ordinary list you can index and slice.

Examples

Iterate keys and values together

scores = {"math": 90, "art": 78}

for subject, score in scores.items():
    print(subject, score)
# math 90
# art 78

The view is dynamic

d = {"a": 1}
view = d.items()

d["b"] = 2                # mutate after calling items()
print(list(view))         # [('a', 1), ('b', 2)] - view saw the change

Convert to a list snapshot

prices = {"pen": 3, "book": 12}

pairs = list(prices.items())
print(pairs)        # [('pen', 3), ('book', 12)]
print(pairs[0])     # ('pen', 3)  - now indexable

Sort entries by value

scores = {"art": 78, "math": 90, "gym": 84}

ranked = sorted(scores.items(), key=lambda kv: kv[1], reverse=True)
print(ranked)   # [('math', 90), ('gym', 84), ('art', 78)]

Swap keys and values in a comprehension

codes = {"red": 1, "green": 2, "blue": 3}

flipped = {value: key for key, value in codes.items()}
print(flipped)   # {1: 'red', 2: 'green', 3: 'blue'}

Filter entries into a new dict

stock = {"pen": 0, "book": 12, "cup": 3, "map": 0}

in_stock = {name: qty for name, qty in stock.items() if qty > 0}
print(in_stock)   # {'book': 12, 'cup': 3}

Diff two dictionaries with set operations

before = {"a": 1, "b": 2, "c": 3}
after = {"a": 1, "b": 9, "c": 3}

changed = after.items() - before.items()
print(changed)   # {('b', 9)}  - only the entry that differs

Browser & runtime support

Views vs lists

Because items() returns a view rather than a list, it is cheap to create no matter how large the dictionary — it copies nothing. That is ideal for a straight for loop, which is the overwhelmingly common case. The trade-off is that a view has no index access and reflects later mutations, so the instant you need a stable, sliceable sequence you must materialise it with list(d.items()).

The view also supports set-like operations, which is a genuinely useful and often-missed feature. Because keys are unique and the pairs are hashable when their values are hashable, you can intersect or difference two items views directly. a.items() & b.items() yields the entries the two dictionaries share exactly — same key *and* same value — while a.items() - b.items() yields the entries in a that b does not match. That makes items() a compact way to diff two dictionaries without writing an explicit comparison loop.

For most day-to-day code, though, you will simply iterate the view once and move on. Reach past a plain for loop only when you have a concrete reason — needing an index, needing a frozen snapshot while you mutate, or diffing two dictionaries — and in each of those cases the fix is the same small step of converting the view or combining it with another.

Availability

dict.items() exists in every version of Python. In Python 3 it returns a dynamic view (the behavior documented here); in the older Python 2 it returned a plain list, with iteritems() giving the lazy variant. On any supported modern Python you get the view.

Frequently asked questions

What does dict.items() return?
A dict_items view object of (key, value) tuples. It is iterable and stays in sync with the dictionary; call list(d.items()) to get a plain, indexable list.
Does dict.items() take any arguments?
No. It takes no arguments — call it as d.items() with empty parentheses on the dictionary you want to iterate.
Why is dict.items() called a dynamic view?
Because the returned view reflects later changes to the dictionary. If you add or remove keys after calling items(), the same view shows the updated pairs — it is a window, not a copy.