COMPUTER PROGRAMMING 1 (PYTHON) • CORE DATA STRUCTURES

Dictionaries for Frequency Counting — I can use dictionaries to count frequencies and build simple histograms at my level.

Learn how Python dictionaries let you tally items and visualize data with simple text-based histograms.

Historical Context & Motivation

Counting things is one of the oldest computational tasks humans have ever performed. Long before computers existed, merchants scratched tally marks into clay tablets to track inventory, and census workers recorded population counts on paper ledgers. The core idea — pairing a category with a count — is exactly what a Python dictionary does when you use it for frequency counting.

In the history of programming, the concept of mapping keys to values evolved from simple lookup tables into one of the most versatile data structures in modern languages. Python's dictionary (the dict type) traces its roots through decades of computer science research on hash tables and associative arrays. Understanding this timeline helps you appreciate why dictionaries are so central to Python programming today.

1953
Hash Tables Invented
IBM researcher Hans Peter Luhn developed hash tables, the underlying data structure that makes dictionaries fast. A hash function converts a key into an index for near-instant lookups.
1969
Associative Arrays in AWK
The AWK language introduced associative arrays — arrays indexed by strings instead of numbers — making key-value mapping accessible to everyday programmers for text processing.
1991
Python 0.9 Includes Dictionaries
Guido van Rossum released the first version of Python, which included dictionaries as a built-in type from day one. This design choice reflected how essential key-value mappings are to real-world programming.
2010s
Big Data & Frequency Analysis
As data science exploded, frequency counting with dictionaries became a foundational skill. Counting word occurrences, analyzing survey responses, and building histograms are now standard tasks taught in introductory CS courses.

So here is the question this lesson answers: given a collection of items — letters in a word, scores in a gradebook, colors of cars in a parking lot — how do you efficiently count how many times each unique item appears, and then display those counts visually? The answer lies in Python's dictionary data structure.

Core Principles & Definitions

Before you start writing code, you need a solid mental model of what a dictionary is and how frequency counting works. A dictionary in Python is a collection of key-value pairs, where each key is unique and maps to exactly one value. When you use a dictionary for frequency counting, the keys represent the items you are counting, and the values represent how many times each item has appeared.

1

Key-Value Pair

A dictionary stores data as pairs. The key identifies the item (e.g., the letter "a"), and the value stores its count (e.g., 3). Written in Python: {"a": 3}.
2

Frequency Counting

Frequency counting means iterating through a collection and tallying how many times each unique item appears. The dictionary starts empty and grows as new items are encountered.
3

The Counting Pattern

For each item: if the key exists, add 1 to its value; if not, create the key with value 1. This is the check-then-increment pattern, used in almost every frequency task.
4

Histogram

A histogram is a visual bar chart that shows the frequency of each item. In a text-based histogram, you print a row of repeated characters (like "*") whose length equals the count.
✦ KEY TAKEAWAY
Think of a dictionary like a class roster clipboard. Each student's name is a key, and the tally marks next to their name (tracking how many times they answered a question, for example) are the value. You scan through the class period, and each time someone speaks, you add a mark next to their name. If it is a new student, you write their name first, then add the mark. That is exactly how frequency counting with a dictionary works.

Visual Explanation — How Frequency Counting Builds a Dictionary

The diagram below traces how a Python dictionary evolves as the program iterates through the string "banana" one character at a time. Each row represents one step of the loop. Notice how the dictionary starts empty and grows each time a new letter is encountered, while existing keys simply get their counts incremented.

The table traces each step of the loop through the string "banana". New keys are created at steps 0, 1, and 2. Steps 3–5 increment existing keys. The bottom shows the resulting text-based histogram.

Notice how the dictionary never contains duplicate keys. Each letter appears exactly once as a key, and its value represents the total number of occurrences. This is the fundamental property that makes dictionaries ideal for frequency counting: the uniqueness constraint on keys naturally groups identical items together, while the values accumulate the counts.

How It Works — The Counting Pattern in Code

Python gives you several ways to implement the frequency counting pattern. Each approach has the same result, but they differ in how they handle the "what if the key doesn't exist yet?" problem. Let's look at the three main techniques, starting from the most explicit and moving to the most concise.

Technique 1: The if-else Check

The most straightforward approach uses an if statement to check whether the key already exists in the dictionary. If it does, you increment its value by 1. If it does not, you create a new entry with a value of 1. Here is the pattern:

IF-ELSE PATTERN
freq = {} for item in data: if item in freq: freq[item] = freq[item] + 1 else: freq[item] = 1
freq = the dictionary accumulating counts. data = any iterable (string, list, etc.). item = each element from data. The in keyword checks for key existence in O(1) average time.

Technique 2: The .get() Method

Python dictionaries have a built-in method called .get() that returns a default value if the key is missing, rather than raising an error. This eliminates the need for an if-else block and makes the code more compact.

GET METHOD PATTERN
freq = {} for item in data: freq[item] = freq.get(item, 0) + 1
freq.get(item, 0) returns the current count if item exists, or 0 if it doesn't. Adding 1 to the result handles both cases in a single line.

Technique 3: Building the Histogram

Once you have a frequency dictionary, you can visualize it as a text-based histogram by looping through the dictionary and printing a repeated character for each count. The string multiplication operator "*" * n repeats the asterisk character n times, producing a horizontal bar proportional to the frequency.

HISTOGRAM OUTPUT PATTERN
for key in freq: print(key, "*" * freq[key])
For each key in the dictionary, this prints the key followed by a row of asterisks. If freq["a"] is 3, it prints a ***. The visual length of each bar directly corresponds to the count.
✦ KEY TAKEAWAY
The .get() method is the Pythonic go-to for frequency counting. It is like asking a librarian, "How many copies of this book do you have?" If the book exists, you get the count; if not, the librarian politely says "zero" instead of giving you an error.

Common Frequency Counting Patterns

Frequency counting appears in many different contexts. The diagram below shows four common patterns you will encounter in Python programming. Each pattern takes a different type of input but follows the same core logic: iterate, check, and count.

Four common applications of the frequency counting pattern. Note how the code in each box is nearly identical — only the variable names and input types change. The .get() method handles all data types uniformly.
Summary of frequency counting patterns by data type
PatternInput TypeKey TypeSplit Needed?
Count charactersstrstr (single char)No — iterating a string yields characters
Count list itemslistSame as element typeNo — iterating a list yields elements
Count wordsstrstr (word)Yes — use .split()
Count numberslistint or floatNo — iterate directly

Worked Example — Counting and Displaying Letter Frequencies

Let's walk through a complete program that counts the frequency of each letter in a user-provided sentence and displays the results as a text-based histogram. We will use the .get() method and handle uppercase/lowercase by converting everything to lowercase first.

Letter Frequency Histogram
1
Step 1 — Define the Input and InitializeWe start with a sentence and create an empty dictionary to hold our frequency counts. We also convert the sentence to lowercase so that "A" and "a" are treated as the same letter. sentence = "Mississippi is a state" sentence = sentence.lower() freq = {}
sentence is now "mississippi is a state" and freq is {}
2
Step 2 — Loop Through Each CharacterWe iterate through every character in the sentence. We only want to count letters, so we skip spaces using .isalpha(), which returns True only for alphabetic characters. for ch in sentence: if ch.isalpha(): freq[ch] = freq.get(ch, 0) + 1
After the loop: {"m": 1, "i": 4, "s": 5, "p": 2, "a": 2, "t": 2, "e": 1}
3
Step 3 — Sort the Dictionary by Count (Descending)To make the histogram more readable, we sort the keys by their frequency in descending order. The sorted() function with key=freq.get sorts by value, and reverse=True puts the highest count first. sorted_keys = sorted(freq, key=freq.get, reverse=True)
sorted_keys = ["s", "i", "p", "a", "t", "m", "e"]
4
Step 4 — Print the HistogramFinally, we loop through the sorted keys and print each letter followed by a bar of asterisks. We use Python's string multiplication to create bars of the right length. for key in sorted_keys: print(key, "*" * freq[key])
Output: s ***** i **** p ** a ** t ** m * e *
💡 Pro Tip
You can make the histogram fancier by using f-strings for alignment: print(f"{key:>3} | {'*' * freq[key]}"). The :>3 right-aligns the key in a 3-character-wide space, keeping your bars neatly lined up.

Dictionaries vs. Other Counting Approaches

You might wonder: why use a dictionary at all? Couldn't you just use a list, or count items one at a time with the .count() method? The table below compares three different approaches to frequency counting so you can see why dictionaries are usually the best choice.

Comparison of frequency counting approaches in Python
ApproachStrengthsLimitations
Dictionary with .get()Counts all items in a single pass through the data. Efficient — O(n) time. Clean, Pythonic code. Works with any hashable type.Requires understanding of dictionaries and the .get() method. Unordered in older Python versions (before 3.7).
list.count() in a loopSimple to understand. No dictionary knowledge needed.Very slow — O(n²) time because .count() scans the entire list for every unique item. Also counts duplicates multiple times unless you track what you've already counted.
Parallel lists (keys + values)Does not require dictionary syntax. Two separate lists for items and counts.Tedious to manage. Must manually keep two lists in sync. Searching for a key requires scanning the items list — O(n) per lookup.
✦ KEY TAKEAWAY
Using a dictionary for frequency counting is like having a filing cabinet with labeled folders. You open the correct folder in one step (that's the O(1) lookup), update the number inside, and move on. The alternatives are like searching through an unsorted pile of papers every time you need to update a count — it works, but it gets painfully slow as the pile grows.

Connection to Advanced Tools

The manual frequency counting pattern you just learned is the foundation for more powerful tools built into Python's standard library and popular third-party packages. As you advance, you will encounter these tools that automate and extend what you can do by hand.

From manual counting to professional-grade tools
What You Know NowAdvanced VersionWhat It Adds
freq.get(item, 0) + 1collections.Counter(data)Counts all items in one line. Includes .most_common(n) to get the top n items, arithmetic between Counters, and more.
Text histogram with "*" * countmatplotlib.pyplot.bar()Creates professional graphical bar charts, pie charts, and other visualizations with colors, labels, and axes.
Manual if/else or .get()collections.defaultdict(int)A dictionary subclass that auto-creates missing keys with a default value (0 for int), eliminating the need for .get() entirely.
Sorting with sorted()pandas.Series.value_counts()Frequency counting integrated into the pandas data analysis library. Returns a sorted series of counts from a DataFrame column.

Even though these advanced tools exist, learning to write frequency counting logic manually is essential. It builds your understanding of iteration, conditionals, and dictionary operations — three pillars of Python programming. When you eventually use Counter or pandas, you will understand exactly what those tools are doing under the hood, which makes debugging far easier.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Explain in your own words why a dictionary is a better data structure for frequency counting than a list. What specific property of dictionaries makes them ideal for this task?
PROBLEM 2 — BASIC CALCULATION
Trace through the following code by hand and write the final value of freq: data = ["red", "blue", "red", "green", "blue", "red"] freq = {} for color in data: freq[color] = freq.get(color, 0) + 1
PROBLEM 3 — INTERMEDIATE
Write a complete Python program that asks the user to input a sentence, then prints a text-based histogram of word frequencies (not character frequencies). Convert all words to lowercase so that "The" and "the" are counted together. Ignore punctuation for simplicity.
PROBLEM 4 — APPLIED
A teacher stores quiz scores in a list: scores = [85, 92, 78, 85, 90, 92, 85, 78, 90, 92, 85, 100]. Write a Python program that (a) counts the frequency of each score, (b) finds which score appeared most often, and (c) prints a histogram sorted from highest score to lowest. Your output should show the score, the count, and a bar of asterisks.
PROBLEM 5 — CRITICAL THINKING
Consider a program that reads a text file containing a novel and builds a word frequency dictionary. The dictionary ends up with 8,000 unique keys. A classmate suggests using list.count() instead of a dictionary because "it's simpler." If the novel has 80,000 words, estimate how many comparison operations each approach requires and explain which is more practical. Then describe one real-world application where word frequency analysis provides meaningful insight.

Lesson Summary

A Python dictionary stores key-value pairs where each key is unique. For frequency counting, the keys represent items being counted and the values store how many times each item appears. The .get() method provides the cleanest implementation: freq[item] = freq.get(item, 0) + 1 handles both new and existing keys in a single line. This pattern works with strings, lists, and any iterable collection. Once you have a frequency dictionary, you can build a text-based histogram by printing repeated characters using "*" * count.

The dictionary approach runs in O(n) time — one pass through the data — making it far more efficient than alternatives like list.count(). You can sort results using sorted() with key=freq.get to display items by frequency. This manual counting skill is the foundation for professional tools like collections.Counter and pandas.value_counts() that you will use in more advanced courses.

Varsity Tutors • Computer Programming 1 (Python) • Dictionaries for Frequency Counting