Dictionary Basics: Creating and Accessing Key-Value Pairs
Character counting uses a dictionary to store each unique character and its count.
Counting Letters with a Dictionary
Imagine that you have the word brontosaurus and want to know how many times each letter appears. A dictionary can store each unique character as a key and its count as the associated value. As the word is processed one character at a time, the program must decide whether the current character is new or has already been counted.
The central decision is simple: a new character receives a count of 1, while an existing character has its current count increased by 1.
Tracing the Dictionary State
The dictionary starts empty. Each character in brontosaurus is examined in sequence. When a character appears for the first time, it is added with the value 1. When a character appears again, its existing value is increased. The dictionary therefore records the counting history as the loop progresses.
The first five characters shown are all new, so each creates a key with value 1. When the next character is o, the dictionary already contains o with a count of 1. That existing count becomes 2 instead of creating another o entry.
The Conditional Counting Pattern
The most explicit approach checks whether the current character is already a key in the dictionary. If it is not present, the program assigns 1 because this is the first occurrence. If it is present, the program adds 1 to the value already stored for that key.
word = "brontosaurus" d = {} for c in word: if c not in d: d[c] = 1 else: d[c] += 1
New Keys and Existing Values
Processing the First Repeated Character
Trace the dictionary while processing the beginning of brontosaurus through the second occurrence of o.
Start: The dictionary is empty before any character is processed.
Process b: b is not a key, so it is initialized with a count of 1.
Process r: r is not a key, so it is initialized with a count of 1.
Process o: o is not a key, so it is initialized with a count of 1.
Process n: n is not a key, so it is initialized with a count of 1.
Process t: t is not a key, so it is initialized with a count of 1.
Process o again: o is already a key with value 1, so its value is increased to 2.
{b: 1, r: 1, o: 2, n: 1, t: 1}
A dictionary has one entry for each unique character. Repeated appearances do not create separate entries; they change the numeric value associated with the existing key.
The Concise get Method
The dictionary get method provides a shorter way to handle both cases. d.get(c, 0) retrieves the current value for c when that key exists. When c does not exist, it supplies the default value 0. Adding 1 and assigning the result back to d[c] therefore initializes a new character to 1 or increments an existing character.
Reading d.get(c, 0) + 1
Explain what happens when c is new and when c already has a count.
New character: If c is missing, d.get(c, 0) produces 0. Adding 1 produces 1, which is stored in d[c].
Existing character: If c is already present, d.get(c, 0) produces its current count. Adding 1 produces the increased count, which is stored back in d[c].
The same update line handles initialization and incrementing.
| Situation | Conditional approach | get method |
|---|---|---|
| Character is new | Set d[c] to 1 | Use default 0, add 1, and store 1 |
| Character already exists | Add 1 to d[c] | Retrieve the existing count, add 1, and store it |
| Result | Character counts are produced | The same character counts are produced |
Mistakes in Character Counting
Incrementing a character before creating its first entry
A new character has no current count to increase in the conditional approach.
Fix:
Initialize a new character with 1, or use d.get(c, 0) so the missing key receives the default value 0 before 1 is added.Treating repeated characters as new entries
The dictionary is meant to keep one key for each unique character and update that key's count.
Fix:
When the character is already present, increase its existing value.Assuming the two approaches produce different counts
Both approaches initialize missing characters and increment existing characters.
Fix:
Trace the new-key and existing-key cases; both approaches produce identical results.
Practice the State Trace
Trace the conditional counting approach for the word "banana". Write the dictionary after processing each character, including the repeated a and n characters.
Hints
- Begin with an empty dictionary.
- A character seen for the first time receives 1.
- A character already in the dictionary has its current count increased by 1.
Explain why d.get(c, 0) + 1 gives the correct update for both a new character and a character that has already been counted.
Hints
- Identify the value returned by get when c is missing.
- Then compare that value with the value returned when c already exists.
- In both cases, 1 is added and the result is stored under c.
Key Takeaways
- A dictionary can store each unique character as a key and its count as the associated value.
- The conditional approach initializes a new character to 1 and increments an existing character by 1.
- The get method uses 0 as the default for a missing character, so d[c] = d.get(c, 0) + 1 handles both cases.
- The conditional and get method approaches produce identical character counts.
- Tracing the dictionary after every character makes initialization and incrementing easier to distinguish.
Key Takeaways
- Use dictionary keys for unique characters and dictionary values for their counts.
- Initialize a character with 1 the first time it appears.
- Increment the existing value when the character appears again.
- The conditional approach and the get method are equivalent character-counting techniques.
- A step-by-step state trace reveals exactly when the dictionary changes.