The Wrong Container gave every group the same job: given a pile of volunteer sign-in lines, answer “how many hours has Rowan done?” Everybody solved it with a list and a loop, and everybody’s solution had the same shape — walk the whole list, compare names, add up. It worked. Then the file grew, and the question got asked once per volunteer, and the loop inside the loop started to show.

The problem was not the loop. It was that a list is organised by position, and nobody at the community centre has ever asked “who is volunteer number 14?” They ask by name. A dictionary is the container that is organised by name.

Lookup by key, not by position

hours = {"Nadia": 4.5, "Rowan": 1.5, "Bea": 2.0}
 
print(hours["Nadia"])
print("Ali" in hours)
print(hours.get("Ali", 0))
4.5
False
0

Each entry is a key and a value. The keys here are names; the values are hours. No loop, no index arithmetic, no searching — and, importantly, the lookup does not get slower as the dictionary grows. That claim has conditions, and Choosing a Data Structure states them honestly.

OperationWritten asNotes
Look uphours["Nadia"]Raises KeyError if absent
Look up safelyhours.get("Ali", 0)Returns the default instead
Add or replacehours["Ali"] = 6.0Same syntax for both
Test a key"Ali" in hoursChecks keys, never values
Removedel hours["Bea"]KeyError if it was not there
Countlen(hours)Number of entries
Loopfor name in hours:Gives the keys
Loop over bothfor name, served in hours.items():Key and value

Keys must be hashable, which in practice means strings, numbers, and tuples — things that do not change underneath the dictionary. A list cannot be a key, and Python refuses the attempt rather than storing something it cannot find again. Values can be anything at all, including lists, objects, and other dictionaries.

The tally pattern

Half of the dictionaries you write this year will be counters, and they all look like this:

signatures = ["soup", "pasta", "soup", "rice", "soup"]
 
counts = {}
for item in signatures:
    if item in counts:
        counts[item] = counts[item] + 1
    else:
        counts[item] = 1
 
print(counts)
{'soup': 3, 'pasta': 1, 'rice': 1}

Start empty. If the key is already there, add to it; if not, create it with the first value. The same four lines, with + quantity instead of + 1, are the heart of Using a Dictionary. Write them enough times and you will recognise the shape in somebody else’s program at a glance — which is most of what reading code well amounts to.

A missing key is a decision, not an accident

hours = {"Nadia": 4.5, "Rowan": 1.5}
print(hours["Ali"])

Choosing between them is a precondition question: does the caller guarantee the key exists? Write your answer in the docstring, because whoever calls your function next cannot read your mind, and the precondition expectation is asking for exactly that sentence.

Order, and what a dictionary will not do for you

Since Python 3.7, dictionaries keep their keys in insertion order. So the tally above comes out in the order the items were first seen — which is arrival order, and rarely the order a human wants to read. Sort at the point of output, with sorted(counts) for keys in alphabetical order, and leave the data alone.

What a dictionary will not do: keep things in sorted order for you, allow duplicate keys (assigning to an existing key replaces its value — silently, which has cost people entire afternoons), or answer questions about values quickly. “Which volunteer has the most hours?” still needs a loop over everything, because the dictionary is indexed by name, not by hours.

Practise in Dictionaries Practice, see it doing real work in Using a Dictionary, and read Choosing a Data Structure before you decide that everything should be a dictionary.

Curriculum connection

C1.1

decompose a problem into modules, classes, or abstract data types (e.g., stack, queue, dictionary) using an object-oriented design methodology (e.g., CRC [Class Responsibility Collaborator] or UML [Unified Modeling Language]);

Link to original

A1.3

demonstrate the ability to use non-numeric comparisons (e.g., strings, comparable interface) in computer programs;

Link to original

C2.1

demonstrate the ability to analyse a precondition (i.e., starting state) and a postcondition (i.e., ending state) in an algorithm;

Link to original