Dictionary Basics: Creating and Accessing
A histogram is a frequency count stored in a dictionary, where keys are unique values (like email addresses) and values are counts of how many times each key appears.
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 Mail Log to Useful Summary
Imagine a mail log containing thousands of messages. The raw messages are difficult to compare directly, but a dictionary can transform them into a frequency summary. In a histogram, each unique value becomes a dictionary key and the value stored for that key is the number of times it appears.
The same counting pattern can answer several related questions. First count messages by full email address, then find the sender with the largest count, and finally count by domain to analyze organizations rather than individual senders.
Building the Email Histogram
A histogram uses a dictionary as a frequency counter. Each email address is a key. When an address appears for the first time, its count starts at zero and is immediately increased to one. When the address appears again, the existing count is retrieved and increased by one. The pattern counts[key] = counts.get(key, 0) + 1 handles both cases in one line.
emails = [
"ana@example.org",
"bo@sample.net",
"ana@example.org",
"ana@example.org",
"bo@sample.net"
]
counts = {}
for email in emails:
counts[email] = counts.get(email, 0) + 1
print(counts)- 1The first appearance of ana@example.org creates a count of 1.
- 2The first appearance of bo@sample.net creates a count of 1.
- 3The next two appearances of ana@example.org raise its count to 3.
- 4The second appearance of bo@sample.net raises its count to 2.
- The empty dictionary will hold the histogram.
- Each email is used as a dictionary key.
get(email, 0)supplies zero when the key is not present.- Adding one records the current appearance.
{'ana@example.org': 3, 'bo@sample.net': 2}Finding the Largest Sender Count
After building the histogram, the most prolific sender can be found with a maximum loop. The loop examines each dictionary entry and keeps two pieces of information: the key belonging to the best entry so far and that entry's count. When a larger count is found, both tracked values are replaced.
ana@example.org
3The two tracking variables must be updated together. The count identifies whether the current entry is better, while the sender records which key produced that count. At the end of the loop, the tracked sender and tracked count describe the highest-frequency dictionary entry.
From Sender Names to Domains
A full email address answers an individual-sender question. A domain answers an organization-level question. To extract the domain, split the email address at the @ symbol and use the second part: email.split('@')[1]. The find method can also locate the @ symbol, after which string slicing can take the text from the position after that symbol.
domain_counts = {}
for email in emails:
domain = email.split('@')[1]
domain_counts[domain] = domain_counts.get(domain, 0) + 1
print(domain_counts)- 1Each full email address is converted into its domain.
- 2Addresses with the same domain use the same dictionary key.
- 3The domain count increases each time any address from that domain appears.
- The
domain_countsdictionary stores frequencies by domain. split('@')[1] selects the text after the @ symbol.- The same histogram pattern counts each extracted domain.
{'example.org': 3, 'sample.net': 2}Mistakes in Histogram Analysis
Common mistake Using a new count of one every time instead of increasing the existing count.
What it looks likecounts[email] = 1Why it failsA repeated key is overwritten with one, so the dictionary does not retain the frequency of earlier appearances.
Do this insteadUse counts[email] = counts.get(email, 0) + 1.Common mistake Tracking only the largest count during the maximum loop.
What it looks likelargest_count is updated, but no sender key is stored.
Why it failsThe final number identifies the frequency but not which dictionary key produced it.
Do this insteadTrack both the sender key and its count whenever a larger count is found.
Common mistake Counting full email addresses when the question is about organizations.
What it looks likeUsing email as the key when comparing domains.
Why it failsDifferent people at the same domain remain separate keys.
Do this insteadExtract domain = email.split('@')[1] and use domain as the histogram key.
Common mistake Selecting the first part after splitting an email address.
What it looks likedomain = email.split('@')[0]Why it failsThe first part is the text before the @ symbol, not the domain.
Do this insteadUse the second part, email.split('@')[1], for the domain.
Before writing the loop, decide what one dictionary key should represent. If the key is a full email address, the result measures individual senders. If the key is a domain, the result measures combined activity from organizations. The histogram pattern stays the same; only the value used as the key changes.
Practice the Three Transformations
Given the email sequence ana@example.org, bo@sample.net, lee@example.org, ana@example.org, and bo@sample.net, write a program that creates a full-address histogram, finds the sender with the highest count, and creates a domain histogram.
Hints
- Start with an empty dictionary for full email counts.
- Use counts[email] =
counts.get(email, 0)+ 1. - For the maximum loop, keep both the winning key and its count.
- Extract each domain with
email.split('@')[1], then apply the same histogram pattern.
What do you think happens?
Before running the domain histogram, predict the count for example.org when ana@example.org appears twice and lee@example.org appears once.
Reveal answer
3
Changing the key from the full email address to the domain combines both senders under example.org, so their appearances contribute to one domain count.
Key Takeaways
- 1A dictionary histogram maps each unique key to the number of times that key appears.
- 2The pattern counts[key] =
counts.get(key, 0)+ 1 handles both new and existing keys. - 3A maximum loop must track both the highest count and the key associated with it.
- 4
email.split('@')[1] extracts the domain for organization-level counting. - 5The choice of key controls the granularity and meaning of the analysis.
At a glance
- Use dictionaries as frequency counters for repeated values.
- Count full email addresses to compare individual senders.
- Track both key and value in a maximum loop to identify the most frequent sender.
- Extract domains with
email.split('@')[1] when the analysis should group senders by organization. - Changing the dictionary key changes the question answered by the histogram.