Python for Humans · Draft v0.1 · Oct 27, 2026 · Draft position: chapter 6 · First draft; build word counts from a small example, then apply them to Shakespeare.
Keeping Count
- You should already know
- Decisions and loops; lists and the Python panel (chapter 4); reading, splitting and lowercasing text (chapter 5).
- You'll build
- A count for every different word in a text.
- You'll be able to
- Create a dictionary, look up and update values by key, check whether a key exists, and build counts with a loop.
- You need
- This page. Python runs in the panel beside it; installing Python on your own computer comes in chapter 9.
Last chapter, we counted one word at a time. But what if we want a count for every different word in Shakespeare?
We could create love_count, king_count, and thousands more variables. Or put the counts in a list, then somehow remember which position belongs to which word.
We need a way to keep each word together with its count. That's what a dictionary gives us.
A Word and Its Count
Open the Python panel and type these commands, pressing Enter after each one. On a small screen, use the Python button. As before, type only what follows >>>.
>>> counts = {'dragon': 2, 'pizza': 3} >>> counts {'dragon': 2, 'pizza': 3} >>> counts['dragon'] 2
Curly braces mark a dictionary. Each entry has two parts separated by a colon: a key and a value. Here the key 'dragon' has the value 2, and the key 'pizza' has the value 3.
With a list, we used a position to ask for an item. With a dictionary, we use a key. counts['dragon'] asks for the value associated with 'dragon'.
The commas separate entries, just as they separated items in a list.
Your turn: Ask for the pizza count. Then create a dictionary called supplies with two supply names as keys and the quantity of each as its value. Look up each quantity.
Change a Count
Suppose another dragon arrives. We can assign a new value to its key:
>>> counts['dragon'] = 3 >>> counts['dragon'] 3
Or we can use the current value to calculate the new one:
>>> counts['dragon'] = counts['dragon'] + 1 >>> counts['dragon'] 4
Python looks up the old count, adds one, then stores the result under the same key. This is the same updating idea we used with variables, now applied to one entry in a dictionary.
Try it: Increase the pizza count by one. Then ask for counts to check that changing one entry hasn't changed the dragon count.
Add a New Key
What if we find a map?
>>> counts['map'] = 1 >>> counts {'dragon': 4, 'pizza': 3, 'map': 1}
If you increased the pizza count in the experiment above, yours will show 4 for pizza. That's fine: the panel remembers your changes.
Assigning to a new key adds an entry. Assigning to an existing key replaces its value; it doesn't create a second copy of the key.
But asking for a key that hasn't been added gives us an error. Try counts['ghost']. You'll see a KeyError because there's no count stored for 'ghost'.
We can check before looking it up:
>>> 'dragon' in counts True >>> 'ghost' in counts False
For a dictionary, in checks the keys. It doesn't search the values.
Your turn: Add 'ghost' with a count of 1, then repeat the membership check. What changes?
Count a Small Collection
Now let's use a loop to build a dictionary. We'll start with three words so we can check every step by hand.
words = ['dragon', 'pizza', 'dragon'] counts = {} for word in words: if word in counts: counts[word] = counts[word] + 1 else: counts[word] = 1 print(counts)
{} creates an empty dictionary. On each trip through the loop, we ask whether we've seen this word before.
- The first word is
'dragon'. It isn't a key yet, so we add it with a count of1. - The second is
'pizza'. It's new too, so it also starts at1. - The third is
'dragon'again. This time the key exists, so we increase its count to2.
We end with {'dragon': 2, 'pizza': 1}.
Predict before changing it: Add another 'pizza' to the list. What should the dictionary contain now? Run it and check. Then try a word that appears only once.
Clean the Words First
Our loop counts exact strings. Just as in the previous chapter, 'Dragon', 'dragon', and 'dragon!' would become separate entries.
We know how to handle capitals. To handle some punctuation too, strings have a method called strip(). It removes any of the characters you give it from the beginning and end of a string.
Try these commands in the panel:
>>> 'dragon!'.strip('.,!?;:') 'dragon' >>> '...pizza?'.strip('.,!?;:') 'pizza' >>> "don't".strip('.,!?;:') "don't"
The punctuation string lists the characters to remove. strip() leaves the middle of the word alone, so the apostrophe in "don't" remains. It also leaves any punctuation we didn't include.
Let's keep cleaning separate from counting for a moment:
text = 'Dragon, pizza! DRAGON.' words = text.split() clean_words = [] for word in words: lowercase_word = word.lower() clean_word = lowercase_word.strip('.,!?;:') if clean_word != '': clean_words.append(clean_word) print(clean_words)
!= means not equal to. The condition keeps a cleaned word only if it isn't the empty string ''. A piece containing just punctuation, such as '...', would otherwise leave an empty entry in our list.
Try it: Add ' ...' to the end of the sample text. Does the output gain an extra word? Then add a new word and check that it appears.
This is a cleanup rule we chose, not a perfect definition of an English word. It leaves quotation marks and many other characters untouched. Different questions may need different rules.
Put the Pieces Together
Here's a starting point for your own word counter. The preparation is supplied. Add the counting loop from Count a Small Collection, then display counts after the loop.
text = 'Dragon, pizza! DRAGON.' words = text.split() counts = {}
First count the strings exactly as they appear. Then put the cleaning steps inside the loop, before updating the dictionary. You can assign the cleaned result back to word and use that name for the rest of the iteration.
Remember to skip empty strings. One way is to put the entire counting decision inside if word != '':.
Your final count should be {'dragon': 2, 'pizza': 1}. Change the sample text to check another repeated word before moving on.
A Worked Version
Compare this with your version after you've tried the task. The cleaning happens before we check the key, so all three spellings of dragon would share one count.
text = 'Dragon, pizza! DRAGON.' words = text.split() counts = {} for word in words: word = word.lower() word = word.strip('.,!?;:') if word != '': if word in counts: counts[word] = counts[word] + 1 else: counts[word] = 1 print(counts)
Your turn: Use a sentence of your own. Before running it, write down the count you expect for one repeated word. Check the actual result against your prediction.
Use the Whole Book
Now keep working in your counter above. Replace its first line with the file-reading command from chapter 5:
text = open('shakespeare.txt').read()
The rest of the counting code can stay the same. A loop that works with a few words can work with hundreds of thousands.
Instead of printing the whole dictionary, change the final line to display just counts['love']. Then add a line showing len(counts): for a dictionary, len() counts the keys. Here that tells us how many distinct cleaned strings we found.
Choose another word and look up its count. If you aren't sure it's present, check if 'your_word' in counts: before asking for its value.
You can also visit the keys with a loop:
for word in counts: if counts[word] > 1000: print(word, counts[word])
Add that loop at the end of your program. It displays words whose counts exceed a thousand, in the dictionary's insertion order, not ranked by frequency. Change the threshold to see more or fewer results.
We now have three different answers to the love question: matching letters anywhere, exact items in a list, and cleaned words. Each answers a slightly different question. Our punctuation rule still leaves some spellings separate, and the file still includes a Gutenberg header and license.
Your Turn
Predict
Write down both outputs before running this:
counts = {'dragon': 2} counts['dragon'] = counts['dragon'] + 1 counts['pizza'] = 1 print(counts['dragon']) print(len(counts))
Find the Bug
This should count two dragons, but reports only one. Find the assignment that throws away the old count.
words = ['dragon', 'pizza', 'dragon'] counts = {} for word in words: counts[word] = 1 print(counts)
Ask a Question of Your Own
Use your counter to investigate a question: which long words appear often, or how many words appear only once?
For the first question, put a length check inside your loop over the dictionary. For the second, start a total at 0 and increase it whenever a key's value is 1. Check your approach with a tiny text before using Shakespeare.
What I've Learned
Write one sentence explaining how a dictionary connects a key to a value. Use a word and its count as your example.
What's Next?
We can count all the words in a text. But each time we want to analyze another text, we have to repeat the same preparation and counting code.
In Giving Code a Name, we'll give that operation a name so we can reuse it without rewriting the loop.