Building Histograms with Dictionaries
A histogram built with a dictionary records how often items occur.
Try it: Counting Words with a Dictionary
The py4e histogram pattern: split each line into words, count them with counts[word] = counts.get(word, 0) + 1, then find the most common word with a max loop or by sorting (count, word) tuples in reverse.
How it works
- Optionally remove punctuation with str.translate and lower-case the line, then split() it into words.
- For each word: counts.get(word, 0) returns the current count or 0 for a new word; store it plus one (or the if word not in counts form).
- A dict remembers insertion order: a word's position is fixed the first time it is seen.
- Max loop: keep the word whose count is strictly larger than the best so far (the first word wins a tie).
- Or build [(count, word) …], sort with reverse=True (ties ordered by the word, reversed) and slice [:N].
Default run (25 steps): Start with an empty dict. The text has 3 lines. … [:3] keeps the top 3: [(5, 'the'), (2, 'sat'), (2, 'on')].
Simplified: Printable-ASCII text up to 320 characters, 8 lines and 60 words, typed in the lab instead of read from a file or URL.
Loading the simulation…
From Items to Counts
A histogram built with a dictionary records how often items occur. Each observed item becomes a dictionary key, and its value records the number of times that item has appeared. The main difficulty is the first occurrence: before an item has been counted, its key may not exist in the dictionary. Python's get() method handles that missing-key case by returning a default value.
What do you think happens?
Suppose counts is an empty dictionary and item is the first value being counted. What starting count should get() provide?
Reveal answer
0
When the key is missing, get() returns the default supplied as its second argument. Starting from 0 makes it possible to add 1 for the item's first occurrence.
How get() Chooses a Value
The get() method looks up a key in a dictionary. If the key exists, get() retrieves the value associated with that key. If the key is missing, get() returns the default value supplied to it. This makes get() useful when a program cannot assume that every key has already been added.
2
0The first lookup finds the existing key red, so the stored value 2 is returned. The second lookup cannot find blue, so the default 0 is returned. The default does not represent a newly stored key by itself; it is the value produced by the lookup when the key is absent.
The Counting Idiom
The standard counting expression is d[c] = d.get(c, 0) + 1. It reads the current count for key c, uses 0 when c is not present, adds 1 for the newly observed item, and stores the resulting count back under c.
counts[item] = counts.get(item, 0) + 1- 1First,
get()retrieves the count associated with item. - 2If item is not yet a key,
get()supplies 0. - 3The expression adds 1 to that count.
- 4The assignment stores the new total under item.
- counts[item]: the dictionary entry that receives the updated count
counts.get(item, 0): the existing count, or 0 when item is missing- + 1: adds the current occurrence
Counting Three Items
Start with an empty dictionary and process the items red, blue, and red.
- 1Process red
red is missing, so
get()returns 0. Adding 1 produces 1, which is stored for red. - 2Process blue
blue is missing, so
get()returns 0. Adding 1 produces 1, which is stored for blue. - 3Process red again
red already has the count 1. Adding 1 produces 2, which replaces the previous count for red.
{"red": 2, "blue": 1}
Refactoring the Loop
Before get() is used, a counting loop commonly needs explicit logic for the two cases: the key is already present, or the key is missing. The get() idiom puts both cases into one assignment. The result is more concise and is described in the source material as more Pythonic and less error-prone when keys may not exist.
counts = {}
for item in items:
if item in counts:
counts[item] = counts[item] + 1
else:
counts[item] = 1The loop explicitly branches depending on whether item is already a key.
counts = {}
for item in items:
counts[item] = counts.get(item, 0) + 1get() supplies 0 for a missing key, so one assignment handles both cases.
The two versions express the same counting idea. In the longer version, the missing-key case assigns 1 directly. In the shorter version, the missing-key case starts at 0 and then adds 1. For an existing key, both versions increase the previous count by 1.
Mistakes with Missing Keys
Common mistake Using bracket notation as though every key already exists
What it looks likecounts[item] = counts[item] + 1Why it failsThe counting expression assumes that item already has a stored count, but the first occurrence may arrive before that key has been added.
Do this insteadUse counts[item] = counts.get(item, 0) + 1 so a missing key starts from the default count 0.
Common mistake Forgetting to add 1 after retrieving the count
What it looks likecounts[item] = counts.get(item, 0)Why it failsThe lookup retrieves the old count or the default, but it does not increase the total for the current occurrence.
Do this insteadAdd 1 before storing the result: counts[item] = counts.get(item, 0) + 1.
Common mistake Using a default other than 0 for a new count
What it looks likecounts[item] = counts.get(item, 1) + 1Why it failsA new item would begin at 1 and then be increased again, so its first occurrence would be counted as 2.
Do this insteadUse 0 as the default starting count, then add 1 for the current item.
Practice the Pattern
Write a loop that builds a histogram for the items in the list ["cat", "dog", "cat", "bird", "dog", "cat"]. Use get() rather than an if-statement. What dictionary should the loop produce?
Hints
- Begin with an empty dictionary named counts.
- For each item, assign counts[item] the result of
counts.get(item, 0)+ 1. - The item cat occurs three times, dog occurs two times, and bird occurs one time.
{"cat": 3, "dog": 2, "bird": 1}Key Takeaways
- 1
get()returns the stored value when a dictionary key exists. - 2When the key is missing,
get()returns the supplied default value. - 3The counting idiom d[c] =
d.get(c, 0)+ 1 handles first and later occurrences in one line. - 4A dictionary histogram maps each observed item to its occurrence count.
- 5Using
get()avoids a separate missing-key branch and is more Pythonic and less error-prone for this counting pattern.
At a glance
get()retrieves an existing dictionary value or returns a chosen default for a missing key.- The default 0 represents the number of earlier occurrences before the current item is counted.
- The expression d[c] =
d.get(c, 0)+ 1 replaces a longer if-statement counting pattern. - Repeatedly applying this expression builds a histogram of item frequencies.