Lesson 77 min read

Dictionaries & Sets

Look things up instantly — like a real dictionary, but for anything

Dictionaries — Key-Value Pairs

A dictionary is like a contact list on your phone. You look up a person's name (the key) and get their phone number (the value). You don't search by position — you search by name. That's what makes dictionaries lightning-fast for lookups — they use a hash function behind the scenes.

Dictionaries are created with curly braces {} and use key: value pairs separated by commas. Keys must be unique and immutable (strings, numbers, or tuples). Values can be anything.

Creating & Using Dictionaries

# Creating a dictionary
player = {
"name": "Link",
"health": 100,
"items": ["sword", "shield", "boomerang"],
"position": (5, 12)
}
# Accessing values
print(player["name"])
print(player["items"])
# Using .get() — safer, returns None if key doesn't exist
print(player.get("score")) # None (no error!)
print(player.get("score", 0)) # Default value: 0
# How many key-value pairs?
print(len(player))
Output
Link
['sword', 'shield', 'boomerang']
None
0
4

CRUD — Create, Read, Update, Delete

Dictionaries are mutable, so you can add, update, and remove entries freely. Here's how to do all four operations:

Modifying Dictionaries

pet = {"name": "Buddy", "type": "dog", "age": 3}
# CREATE — add new key
pet["color"] = "golden"
# UPDATE — change existing key
pet["age"] = 4
# DELETE — several ways
removed = pet.pop("color") # Remove and return value
print(f"Removed: {removed}")
del pet["type"] # Delete by key
print(pet)
# Merge dictionaries
defaults = {"lives": 3, "speed": 5}
bonus = {"speed": 10, "shield": True}
combined = {**defaults, **bonus} # bonus overwrites conflicts
print(combined)
# .update() method
defaults.update(bonus)
print(defaults)
Output
Removed: golden
{'name': 'Buddy', 'age': 4}
{'lives': 3, 'speed': 10, 'shield': True}
{'lives': 3, 'speed': 10, 'shield': True}

Looping Through Dictionaries

Dictionaries give you three ways to iterate: over keys, values, or both (items). The .items() method is the most common — it gives you tuples of (key, value) that you can unpack right in the loop.

Iterating & Useful Patterns

grades = {"math": 92, "science": 87, "english": 95, "art": 88}
# Loop through keys (default)
for subject in grades:
print(subject)
print() # blank line
# Loop through values
print(f"Average: {sum(grades.values()) / len(grades):.1f}")
# Loop through key-value pairs
for subject, score in grades.items():
status = "Pass" if score >= 90 else "Good"
print(f"{subject}: {score} ({status})")
print()
# Check if key exists
if "math" in grades:
print(f"Math grade: {grades['math']}")
# Counting pattern
word = "mississippi"
letter_count = {}
for char in word:
letter_count[char] = letter_count.get(char, 0) + 1
print(letter_count)
Output
math
science
english
art

Average: 90.5
math: 92 (Pass)
science: 87 (Good)
english: 95 (Pass)
art: 88 (Good)

Math grade: 92
{'m': 1, 'i': 4, 's': 4, 'p': 2}

Sets — Unique Items Only

A set is like a bag of unique marbles — you can't have duplicates, and there's no specific order. Sets are fantastic for removing duplicates, testing membership, and doing math-like operations (union, intersection, difference).

Sets & Set Operations

# Creating sets
fruits = {"apple", "banana", "cherry", "apple"} # duplicate removed!
print(fruits)
print(len(fruits)) # 3, not 4
# Remove duplicates from a list
numbers = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(numbers))
print(unique)
# Set operations
backend = {"Python", "Java", "Go", "Rust"}
frontend = {"JavaScript", "TypeScript", "Python"}
print(f"Union: {backend | frontend}") # All languages
print(f"Intersection: {backend & frontend}") # In both
print(f"Backend only: {backend - frontend}") # In backend, not frontend
print(f"Exclusive: {backend ^ frontend}") # In one but not both
# Fast membership testing
allowed = {"admin", "editor", "viewer"}
role = "editor"
print(role in allowed) # Much faster than checking a list!
Output
{'cherry', 'banana', 'apple'}
3
[1, 2, 3, 4]
Union: {'Go', 'TypeScript', 'Java', 'JavaScript', 'Python', 'Rust'}
Intersection: {'Python'}
Backend only: {'Go', 'Java', 'Rust'}
Exclusive: {'Go', 'TypeScript', 'Java', 'JavaScript', 'Rust'}
True
Note: Checking x in my_set is blazing fast (constant time), while x in my_list gets slower as the list grows. If you're checking membership frequently, convert your list to a set first!

Quick check

What happens when you access a key that doesn't exist with my_dict["missing"]?

Continue reading

Hash FunctionsData Structure
Collisions, load factor, probing
Sets vs MapsData Structure
Use cases and tradeoffs
ObjectsJavascript
Key-value pairs — the backbone of JS
Collections FrameworkJava
List, Set, Map — the power tools of Java
Lists & TuplesFunctions