You've greeted people and made decisions. Today you're going to count things — and counting is where two of Python's most important tools show up together: the dictionary and the for loop.
Let's say you have a sentence: "the cat sat on the mat". How many times does each word appear? You could read it by eye, but what if the sentence is a thousand words long?
I'd probably make a tally chart — write each new word down and put a mark next to it every time I see it again.
That is exactly what a dictionary does. In Python, a dictionary stores key-value pairs — each unique word is a key, and its count is the value:
counts = {}
counts["the"] = 2
counts["cat"] = 1
counts["sat"] = 1
print(counts) # {'the': 2, 'cat': 1, 'sat': 1}Curly braces create an empty dictionary. You add entries by writing dictionary[key] = value. You look entries up the same way: counts["the"] gives you 2.
But I still have to add each word by hand. What if the sentence changes?
That's where the for loop comes in. A loop lets you visit every item in a sequence automatically. Pair a loop with a dictionary and your tally chart writes itself:
words = ["the", "cat", "sat", "on", "the", "mat"]
counts = {}
for word in words:
if word in counts:
counts[word] += 1
else:
counts[word] = 1
print(counts) # {'the': 2, 'cat': 1, 'sat': 1, 'on': 1, 'mat': 1}Read it out loud: "For each word in the list — if I've seen this word before, add one to its count. Otherwise, start its count at one." That's the whole algorithm. word in counts checks whether the key already exists. += 1 is shorthand for "add one to the current value."
Wait — += 1 is the same as writing counts[word] = counts[word] + 1?
Exactly. It's just shorter. Most Python programmers reach for += without thinking about it after a week. You'll do the same.
What happens if I access a key that's not in the dictionary? Like if I wrote counts["zebra"] on an empty dict?
Python raises a KeyError — it refuses to guess. That's why the if word in counts check matters. It's the gate that separates "I've seen this word before" from "this is the first time." Skip the check and your first += 1 on a brand-new word crashes immediately because there's nothing there to add to.
The first-time path sets the count to 1 precisely because this is the inaugural sighting. Every subsequent visit adds one more.
So the whole trick is: check if the key exists, then either increment or initialize. That's it?
That's the whole pattern. It shows up constantly in real programs — counting votes, tallying inventory, tracking which users have seen a notification. Once you've written it once, you'll recognise it everywhere. Now you're going to write the full thing: take any string of text, split it into words, and return the complete count dictionary.
Counting words is a classic programming exercise because it forces two fundamental ideas to work together: a data structure that stores labeled counts, and a loop that processes every item in a sequence.
A Python dictionary maps keys to values. Keys are unique — if you assign to a key that already exists, the old value is replaced. This property is what makes dictionaries perfect for tallying: the word is the key, the running total is the value.
counts = {} # empty dictionary
counts["hello"] = 1 # create an entry
counts["hello"] += 1 # update it — now 2The in operator tests whether a key exists without raising an error. Always use it (or .get()) before reading a key you are not certain is present.
A for loop iterates over any sequence — lists, strings, the lines of a file. For word counting, the sequence is the list of words produced by str.split():
"Hello World".lower().split() # ['hello', 'world']Calling .lower() first collapses casing: "Hello" and "hello" and "HELLO" all become the same key.
Every word falls into one of two cases on each loop iteration:
1.1 to its current value.This pattern is so common it has a standard shorthand using dict.get() with a default:
counts[word] = counts.get(word, 0) + 1dict.get(key, default) returns the stored value if the key exists, or default if it does not — eliminating the explicit if/else. Both styles produce identical results; the explicit version is easier to read when you are just learning.
The same dictionary-plus-loop structure powers a surprising range of real applications: vote tallying, inventory tracking, log analysis, building frequency tables for recommendation systems. The shape of the code is always the same — only the thing being counted changes.
Sign up to write and run code in this lesson.
You've greeted people and made decisions. Today you're going to count things — and counting is where two of Python's most important tools show up together: the dictionary and the for loop.
Let's say you have a sentence: "the cat sat on the mat". How many times does each word appear? You could read it by eye, but what if the sentence is a thousand words long?
I'd probably make a tally chart — write each new word down and put a mark next to it every time I see it again.
That is exactly what a dictionary does. In Python, a dictionary stores key-value pairs — each unique word is a key, and its count is the value:
counts = {}
counts["the"] = 2
counts["cat"] = 1
counts["sat"] = 1
print(counts) # {'the': 2, 'cat': 1, 'sat': 1}Curly braces create an empty dictionary. You add entries by writing dictionary[key] = value. You look entries up the same way: counts["the"] gives you 2.
But I still have to add each word by hand. What if the sentence changes?
That's where the for loop comes in. A loop lets you visit every item in a sequence automatically. Pair a loop with a dictionary and your tally chart writes itself:
words = ["the", "cat", "sat", "on", "the", "mat"]
counts = {}
for word in words:
if word in counts:
counts[word] += 1
else:
counts[word] = 1
print(counts) # {'the': 2, 'cat': 1, 'sat': 1, 'on': 1, 'mat': 1}Read it out loud: "For each word in the list — if I've seen this word before, add one to its count. Otherwise, start its count at one." That's the whole algorithm. word in counts checks whether the key already exists. += 1 is shorthand for "add one to the current value."
Wait — += 1 is the same as writing counts[word] = counts[word] + 1?
Exactly. It's just shorter. Most Python programmers reach for += without thinking about it after a week. You'll do the same.
What happens if I access a key that's not in the dictionary? Like if I wrote counts["zebra"] on an empty dict?
Python raises a KeyError — it refuses to guess. That's why the if word in counts check matters. It's the gate that separates "I've seen this word before" from "this is the first time." Skip the check and your first += 1 on a brand-new word crashes immediately because there's nothing there to add to.
The first-time path sets the count to 1 precisely because this is the inaugural sighting. Every subsequent visit adds one more.
So the whole trick is: check if the key exists, then either increment or initialize. That's it?
That's the whole pattern. It shows up constantly in real programs — counting votes, tallying inventory, tracking which users have seen a notification. Once you've written it once, you'll recognise it everywhere. Now you're going to write the full thing: take any string of text, split it into words, and return the complete count dictionary.
Counting words is a classic programming exercise because it forces two fundamental ideas to work together: a data structure that stores labeled counts, and a loop that processes every item in a sequence.
A Python dictionary maps keys to values. Keys are unique — if you assign to a key that already exists, the old value is replaced. This property is what makes dictionaries perfect for tallying: the word is the key, the running total is the value.
counts = {} # empty dictionary
counts["hello"] = 1 # create an entry
counts["hello"] += 1 # update it — now 2The in operator tests whether a key exists without raising an error. Always use it (or .get()) before reading a key you are not certain is present.
A for loop iterates over any sequence — lists, strings, the lines of a file. For word counting, the sequence is the list of words produced by str.split():
"Hello World".lower().split() # ['hello', 'world']Calling .lower() first collapses casing: "Hello" and "hello" and "HELLO" all become the same key.
Every word falls into one of two cases on each loop iteration:
1.1 to its current value.This pattern is so common it has a standard shorthand using dict.get() with a default:
counts[word] = counts.get(word, 0) + 1dict.get(key, default) returns the stored value if the key exists, or default if it does not — eliminating the explicit if/else. Both styles produce identical results; the explicit version is easier to read when you are just learning.
The same dictionary-plus-loop structure powers a surprising range of real applications: vote tallying, inventory tracking, log analysis, building frequency tables for recommendation systems. The shape of the code is always the same — only the thing being counted changes.