These questions ask you to predict dictionary lookup, membership, ordering, mutation and copying. Treat a dictionary as an insertion-ordered mapping, then identify exactly which side of each pair the operation examines.
Follow unique hashable labels through the mapping
Each entry has a unique hashable lookup label and a value. A mutable list is unhashable, so it cannot serve as that label. Equal labels cannot coexist: when a literal supplies one again, the later value replaces the earlier value. Try data = dict(red=2) followed by data['red'] = 5: the existing entry receives a new value.
An empty pair of braces creates a dictionary; an empty set needs an explicit constructor. Ordinary iteration follows insertion order and yields lookup labels. Replacing the value of an existing entry keeps its original position rather than moving it to the end.
| Operation | Method |
|---|---|
| Subscription | Return the mapped value, or raise KeyError when the requested label is absent. |
| get with a default | Return the mapped value when present, otherwise return the default without inserting anything. |
| Membership with in | Search lookup labels, not mapped values. |
| Deletion | Remove the named entry, or raise KeyError when it is absent. |
The results of keys, values and items are dynamic views connected to the dictionary. A view obtained before a mutation can reveal the later state. Items produces a two-item tuple for each entry, containing its lookup label and corresponding value.
The copy method creates a distinct outer dictionary but copies references to its values. Try clone = data.copy(): changing which value clone maps independently changes only clone, but mutating a nested list value can be visible through both mappings because that inner object remains shared.
Reject the tempting wrong routes
| Trap | How to reject it |
|---|---|
| Assuming that only strings may label entries | Check hashability rather than type. Other hashable objects can be used, while a list is unhashable. |
| Calling empty braces a set or preserving repeated equal labels | Empty braces mean dictionary, and equal labels identify one entry whose later value replaces its earlier value. |
| Treating subscription, get and deletion as identical missing-entry operations | Subscription and deletion raise KeyError when absent. Get returns its default and does not create an entry. |
| Searching mapped values with in | Plain dictionary membership examines lookup labels only; values require an explicit values view. |
| Freezing a previously obtained view | A view remains connected to its dictionary, so later additions and removals can appear through it. |
| Treating copy as either a complete alias or a recursive copy | The outer mappings are distinct, but nested mutable values can still be the same objects. |
Try it
A dictionary receives keys in the order `b`, `a`, then `c`. In what order does ordinary iteration yield those keys?
- A new random order each time
- `a`, `b`, `c` because keys are sorted
- `b`, `a`, `c` in insertion order
- The values rather than the keys
A program runs `data = dict(a=1, b=2)` and then assigns 3 to the existing key `a`. What does `list(data.items())` return?
- `[("a", 1), ("b", 2), ("a", 3)]`
- `[("a", 1), ("b", 2)]`
- `[("b", 2), ("a", 3)]`
- `[("a", 3), ("b", 2)]`
What is the shape of each element produced by `data.items()`?
- A value with no key
- A mutable two-element list
- A two-item tuple of key and value
- A one-item tuple containing the key