Stop using parallel lists. Start using dictionaries.
Timothy was hunched over his desk, his finger tracing a line across his screen. He looked like he was trying to solve a word search puzzle.
"Found it," he muttered, typing a number. Then he scrolled back up, traced another line, and typing again.
Margaret watched him for a moment. "You look like a man searching for a needle in a stack of needles."
"I'm building a phone directory," Timothy said, not looking up. "I have a list of customer names and a list of their ID numbers. When I need to find a customer's ID, I have to find their position in the names list, and then grab the item at the same position in the ids list."
He showed her his code.
# Timothy's "Parallel List" Strategy
names = ["Alice", "Bob", "Charlie", "Dave"]
ids = [101, 102, 103, 104]
def find_id(name_to_find):
# Step 1: Find the index of the name
# (Timothy scans the whole list until he finds a match)
for i in range(len(names)):
if names[i] == name_to_find:
# Step 2: Use that index to get the ID
return ids[i]
return "Not Found"
print(find_id("Charlie"))
Output:
103
"It works," Timothy said. "I keep the lists perfectly synchronized. Index 2 is Charlie, Index 2 is his ID. Parallel lines."
"It works," Margaret corrected, "until you have a million customers. Then, to find 'Zoe', you must walk past every single person from 'Alice' to 'Yvonne'. You are walking the entire length of the library just to find one book."
The Desynchronization Trap
"Worse," Margaret warned, "what happens if someone leaves?"
She pointed to the lists. "If you delete 'Charlie' from the names list, but forget to touch the IDs list, the entire world shifts."
# The Fragility Problem
names = ["Alice", "Bob", "Charlie", "Dave"]
ids = [101, 102, 103, 104]
# Oops! We remove Charlie, but forget to update the IDs
del names[2]
# Now "Dave" slides into Index 2
print(f"Index 2 is now: {names[2]}")
print(f"But ID at index 2 is: {ids[2]}")
Output:
Index 2 is now: Dave
But ID at index 2 is: 103
Timothy gasped. "Dave stole Charlie's ID!"
"This is the Parallel List Trap," Margaret said. "You are trying to glue two separate lists together using only your own willpower. It is slow, because you have to search. And it is fragile, because one slip breaks the link forever."
Margaret's Solution: A Dictionary
"So how do I link them?" Timothy asked. "I need a way to say 'Alice equals 101'."
"You do not need a list," Margaret said. "You need a Dictionary."
She opened a large, leather-bound volume on the table. "In a dictionary, you do not search page by page. You simply know the word, and you go directly to the definition."
She deleted his two lists and replaced them with a single structure using curly braces {}.
# Margaret's Solution: The Dictionary (Hash Map)
customer_directory = {
"Alice": 101,
"Bob": 102,
"Charlie": 103,
"Dave": 104
}
# No loops. No scanning. Just instant retrieval.
print(customer_directory["Charlie"])
Output:
103
"Where is the loop?" Timothy asked. "How did it find Charlie?"
"It didn't 'find' him," Margaret said. "It calculated him. A Dictionary (or Hash Map) uses the key ('Charlie') to calculate the exact address in memory where the value (103) lives. It jumps straight there."
The Speed of Light
"Is it faster?"
Margaret raised an eyebrow. "Timothy, if you have a list of one million names, and you want to find the last one, your loop has to check one million items. That is ."
"With a Dictionary," she continued, "it effectively takes one step. Just one. It doesn't matter if you have ten names or ten billion. The time to find the key is constant. That is ."
Timothy looked at his clunky parallel lists. "So I've been running a marathon every time I wanted to look up a phone number."
"Precisely," Margaret said.
Margaret’s Cheat Sheet
Margaret opened her notebook to the "Data Structures" section.
-
The Trap: Using two lists (
names,ages) and trying to keep them in sync. This is called Parallel Lists. - The Problem: Searching is slow (). Maintenance is dangerous (easy to desynchronize).
-
The Fix: Use a Dictionary
{key: value}. - The Syntax:
- Create:
my_dict = {"Key": "Value"} - Alternative:
my_dict = dict(Key="Value") - Access:
value = my_dict["Key"] Add/Update:
my_dict["New Key"] = "New Value"The Superpower: Lookups are instant ().
Timothy deleted his loop and replaced it with the single lookup line. "It feels like teleportation," he murmured.
"It is," Margaret smiled, closing the book. "Why walk when you can jump?"
In the next episode, Margaret and Timothy will face "The Default Danger"—where a simple default argument in a function creates a zombie variable that never dies.
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.
Top comments (2)
This is such a clean way to explain a mistake almost everyone makes at some point. The “Dave stole Charlie’s ID” moment is exactly how these bugs feel in real code — confusing and slightly terrifying 😄
I really like how you didn’t just say “use a dictionary because it’s faster,” but showed why parallel lists fail both in performance and in maintenance. The desynchronization example is painfully realistic.
The dictionary-as-teleportation analogy lands nicely too. Once you internalize that you’re jumping directly to data instead of walking through it, it’s hard to ever go back to parallel lists.
These story-driven explanations make core data structure ideas stick way better than abstract Big-O charts. Great read.
✨🙏