Iterating Through Strings with For Loops
When the loop reaches the first character, that character is not yet a key, so the dictionary receives a new entry with the value 1.
From Letters to Counts
Suppose you want to know how many times each character appears in the word "brontosaurus". A dictionary can store this information by using each unique character as a key and its occurrence count as the value. A for loop examines the string one character at a time, and the counting logic decides whether that character is new or has already been counted.
The central decision is simple: a character seen for the first time receives a count of 1; a character already in the dictionary has its existing count increased by 1.
Tracing the Dictionary
The dictionary changes after every loop iteration. At the beginning, it is empty. When the loop reaches the first character, that character is not yet a key, so the dictionary receives a new entry with the value 1. Later, a repeated character does not create another key. Instead, its existing value increases.
The important change occurs when the second o is processed. The key o already exists with a count of 1, so the value becomes 2. The loop still processes one character at a time, but the dictionary update depends on whether that character has appeared before.
The Conditional Method
The most explicit approach checks whether the current character is already a key in the dictionary. If it is not present, the code creates an entry with a count of 1. If it is present, the code adds 1 to the stored count.
word = "brontosaurus"
d = {}
for c in word:
if c not in d:
d[c] = 1
else:
d[c] = d[c] + 1- 1The variable word contains the text to inspect.
- 2The variable d starts as an empty dictionary.
- 3The for loop visits each character in word in sequence.
- 4The condition c not in d tests whether this character has been seen before.
- 5The first branch initializes a new character count.
- 6The else branch increments the existing count.
- The string supplies the characters that the loop processes.
- The empty dictionary will store each character and its count.
- Each iteration assigns the next character to c.
- A character that is not already a key receives the initial count 1.
- A character that is already a key has its current count increased by 1.
Processing the First Six Characters
Trace the dictionary while processing the characters b, r, o, n, t, and o from "brontosaurus".
- 1b
b is not in the empty dictionary, so create the entry b: 1.
- 2r
r is new, so add r: 1 while keeping b: 1.
- 3o
o is new, so add o: 1.
- 4n
n is new, so add n: 1.
- 5t
t is new, so add t: 1.
- 6o again
o is already present with count 1, so increase its value to 2.
{'b': 1, 'r': 1, 'o': 2, 'n': 1, 't': 1}
Why Initialization Matters
Initialization and incrementing are different operations. Initialization creates the dictionary entry because the character has no stored count yet. The value must be 1 because the current loop iteration is the first occurrence. Incrementing is used only after the key exists; it raises the stored count by 1 to include the new occurrence.
The get Method
Python's dictionary get method provides a shorter way to handle both cases. The expression d.get(c, 0) returns the current value for c when c exists. When c does not exist, it returns the supplied default value 0. Adding 1 and assigning the result back to d[c] therefore works for both a new character and an existing character.
- For a new character,
d.get(c, 0)supplies 0, and adding 1 stores 1. - For an existing character,
d.get(c, 0)supplies its current count, and adding 1 increases it.
Expanding the Single Line
Explain how d[c] = d.get(c, 0) + 1 handles a new character and a repeated character.
- 1New character
If c is not a key,
d.get(c, 0)returns the default 0. The expression adds 1 and stores d[c] as 1. - 2Existing character
If c is already a key,
d.get(c, 0)returns its current count. The expression adds 1 and stores the increased value. - 3Same update rule
Both cases add 1 to a value and assign the result to d[c]. The default value makes the new-character case behave like the first count.
The get method combines initialization and incrementing into one expression.
Two Equivalent Approaches
The conditional approach and the get method approach produce identical character-count dictionaries. They differ mainly in how explicitly they show the two cases. The conditional version names the new-character and existing-character branches separately. The get version uses 0 as the missing-key value, then adds 1 in either case.
| Approach | New character | Existing character | Style |
|---|---|---|---|
| Conditional | Assign 1 | Add 1 to the stored count | More explicit |
| get method | get returns 0, then add 1 | get returns the stored count, then add 1 | More concise |
Both approaches update the dictionary once for each character and produce identical results.
Use the approach that makes the code clearest to you and your teammates. The conditional form can be easier for beginners to read because it displays each case separately. The get form is shorter and remains readable once the default-value behavior is understood.
Mistakes in Character Counting
Common mistake Initializing an existing character instead of incrementing it
What it looks likeAssigning d[c] = 1 every time c is processed
Why it failsA repeated character is reset to 1 rather than preserving and increasing its current count.
Do this insteadCheck whether c is already in d. Initialize only a new character, and increment the existing value otherwise.
Common mistake Incrementing a character before creating its first entry
What it looks likeUsing the existing-count branch when c is not yet a key
Why it failsThe counting logic needs an initial value before it can increase that value.
Do this insteadFor a missing key, create d[c] with the value 1.
Common mistake Treating repeated characters as separate keys
What it looks likeCreating a new dictionary entry for every occurrence of o
Why it failsThe dictionary should store each unique character with one count that changes as more occurrences are processed.
Do this insteadKeep one key for the character and update its value when the character appears again.
Common mistake Assuming the two approaches produce different counts
What it looks likeExpecting the conditional version and d.get(c, 0) + 1 to have different final results
Why it failsThe two implementations use different syntax but apply the same initialization-or-increment logic.
Do this insteadCompare their final dictionaries; both approaches count each character identically.
Practice the Trace
Trace the dictionary after each character in the string "aba" is processed using the conditional approach. Write the dictionary after the first a, after b, and after the final a. Then explain why the final a increments an existing count instead of creating a new entry.
Hints
- Start with an empty dictionary.
- For the first occurrence of a character, assign a count of 1.
- For the second occurrence of a character, increase its existing count by 1.
What do you think happens?
After processing the string "aba" with d[c] = d.get(c, 0) + 1, what dictionary should remain?
Reveal answer
{'a': 2, 'b': 1}
The first a uses the default 0 and becomes 1. b also uses the default 0 and becomes 1. The final a retrieves its existing count of 1 and increases it to 2.
Key Takeaways
- 1A for loop processes the string one character at a time.
- 2A dictionary stores each unique character as a key and its occurrence count as the value.
- 3The conditional approach initializes a new character to 1 and increments an existing character by 1.
- 4The get approach uses
d.get(c, 0)+ 1 to handle both cases in one expression. - 5The conditional and get approaches produce identical character-count dictionaries.
At a glance
- Use a dictionary to connect each unique character with its count.
- Initialize a count when a character appears for the first time.
- Increment the stored count when the character appears again.
- The get method uses a default value of 0 to combine both cases in one line.
- Tracing the dictionary after each loop iteration reveals how the final counts are built.