Dictionaries and Sets
In the last two lessons we covered lists and tuples, which are accessed "by position." But in real life, we often look things up "by name" — dictionaries by word, contacts by name. Dictionaries (dict) handle this. Sets are for mathematical set operations. Both are extremely useful in data processing.
1. What Is a Dictionary
A dictionary is defined with curly braces {}, containing a set of key-value pairs, separated by colons.
# Define a dictionary
student = {
"name": "Alice",
"age": 20,
"city": "Beijing"
}
print(student) # {'name': 'Alice', 'age': 20, 'city': 'Beijing'}
print(type(student)) # <class 'dict'>
Basic CRUD Operations
# Create a dictionary
user = {}
# Add / modify key-value pairs
user["name"] = "Alice"
user["age"] = 25
print(user) # {'name': 'Alice', 'age': 25}
# Modify an existing key
user["age"] = 26
print(user) # {'name': 'Alice', 'age': 26}
# Read a value
print(user["name"]) # Alice
# print(user["email"]) # KeyError! Non-existent key raises error
# Use get() for safe access — returns default if key doesn't exist
print(user.get("email")) # None — not found, returns None
print(user.get("email", "not set")) # not set — custom default
# Delete a key-value pair
del user["age"]
print(user) # {'name': 'Alice'}
dict["non_existent_key"] raises KeyError. Use get() to avoid this — it returns None or your specified default.
Example: Student Info Management (Difficulty ⭐)
# Store a student's full info in a dictionary
student = {
"name": "Bob",
"id": "2024001",
"scores": {"Chinese": 85, "Math": 92, "English": 78},
"is_active": True
}
# Read basic info
print(f"Name: {student['name']}")
print(f"ID: {student['id']}")
# Read from nested dictionary
math_score = student["scores"]["Math"]
print(f"Math score: {math_score}")
# Safe access with get
phone = student.get("phone", "not filled")
print(f"Phone: {phone}")
Output:
Name: Bob
ID: 2024001
Math score: 92
Phone: not filled
2. Common Dictionary Methods
Getting All Keys, Values, and Key-Value Pairs
user = {"name": "Alice", "age": 25, "city": "Beijing"}
print(user.keys()) # dict_keys(['name', 'age', 'city'])
print(user.values()) # dict_values(['Alice', 25, 'Beijing'])
print(user.items()) # dict_items([('name', 'Alice'), ('age', 25), ('city', 'Beijing')])
# Most common way to iterate a dictionary
for key, value in user.items():
print(f"{key} = {value}")
Output:
name = Alice
age = 25
city = Beijing
pop() and setdefault()
# pop() — remove and return the value for a key
user = {"name": "Alice", "age": 25, "city": "Beijing"}
city = user.pop("city")
print(f"Removed city: {city}") # Removed city: Beijing
print(user) # {'name': 'Alice', 'age': 25}
# pop() can specify a default, avoiding KeyError
email = user.pop("email", "no email")
print(email) # no email — key doesn't exist, returns default
# setdefault() — if key exists, return its value; if not, insert the default
user = {"name": "Alice"}
result = user.setdefault("age", 18)
print(user) # {'name': 'Alice', 'age': 18}
# If key already exists, setdefault doesn't modify it
result = user.setdefault("name", "Bob")
print(user) # {'name': 'Alice', 'age': 18} — unchanged
update() — Merging Dictionaries
# Merge two dictionaries
defaults = {"theme": "light", "lang": "en", "font_size": 14}
custom = {"theme": "dark", "font_size": 16}
defaults.update(custom) # custom overwrites matching keys in defaults
print(defaults) # {'theme': 'dark', 'lang': 'en', 'font_size': 16}
Example: Word Count (Difficulty ⭐⭐)
# Count word occurrences in a sentence
text = "apple banana apple orange banana apple"
word_count = {}
for word in text.split():
# If word is already in dict, increment; otherwise, set to 1
word_count[word] = word_count.get(word, 0) + 1
print(word_count) # {'apple': 3, 'banana': 2, 'orange': 1}
# Output with items()
for word, count in word_count.items():
print(f"{word}: {count} times")
Output:
apple: 3 times
banana: 2 times
orange: 1 times
3. Dictionary Iteration and Nesting
Three Ways to Iterate a Dictionary
user = {"name": "Alice", "age": 25, "city": "Beijing"}
# Method 1: iterate over keys
for key in user: # Equivalent to for key in user.keys():
print(f"{key}: {user[key]}")
# Method 2: iterate over values
for value in user.values():
print(value)
# Method 3: iterate over key-value pairs (recommended)
for key, value in user.items():
print(f"{key} → {value}")
Nested Dictionaries
# Nested dictionary — storing multiple student records
students = {
"1001": {"name": "Alice", "scores": [85, 90, 78]},
"1002": {"name": "Bob", "scores": [92, 88, 95]},
"1003": {"name": "Charlie", "scores": [76, 85, 82]},
}
# Iterate over nested dictionary
for sid, info in students.items():
name = info["name"]
avg = sum(info["scores"]) / len(info["scores"])
print(f"{sid} {name}: Average {avg:.1f}")
Output:
1001 Alice: Average 84.3
1002 Bob: Average 91.7
1003 Charlie: Average 81.0
4. What Is a Set
A set is defined with curly braces {} or set(). It looks like a dictionary but has no values, only keys. Sets are: unique elements, unordered.
# Define a set
fruits = {"apple", "banana", "orange", "apple"} # Duplicates are auto-removed
print(fruits) # {'orange', 'apple', 'banana'} — order may vary
# Create a set from a list
numbers = set([1, 2, 2, 3, 3, 3])
print(numbers) # {1, 2, 3} — duplicates removed
# Empty set must use set(), not {} ({} is an empty dict)
empty_set = set()
print(type(empty_set)) # <class 'set'>
list(set(list_name)) quickly removes duplicates. But note that sets are unordered, so the original order is lost.
Basic Set Operations
# Add and remove
s = set()
s.add("apple")
s.add("banana")
s.add("apple") # Duplicate add has no effect
print(s) # {'apple', 'banana'}
s.discard("apple") # Remove; no error if not found
print(s) # {'banana'}
# s.remove("non_existent") # Would raise KeyError!
5. Set Operations
This is where sets truly shine — mathematical intersection, union, and difference:
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
# Intersection — elements present in both sets
print(a & b) # {4, 5}
print(a.intersection(b)) # Same
# Union — all elements from both sets (no duplicates)
print(a | b) # {1, 2, 3, 4, 5, 6, 7, 8}
print(a.union(b)) # Same
# Difference — elements in a but not in b
print(a - b) # {1, 2, 3}
print(a.difference(b)) # Same
# Symmetric difference — elements in a or b but not both
print(a ^ b) # {1, 2, 3, 6, 7, 8}
Example: User Permission Analysis (Difficulty ⭐⭐⭐)
# Simulate social platform user relationships
all_users = {"Alice", "Bob", "Charlie", "Diana", "Eve"}
vip_users = {"Bob", "Diana", "Eve"}
blocked_users = {"Diana"}
# Find "normal users who are not VIP"
normal_users = all_users - vip_users - blocked_users
print(f"Normal users: {normal_users}")
# Find "active VIPs (not blocked)"
active_vip = vip_users - blocked_users
print(f"Active VIPs: {active_vip}")
# Find "blocked users who are VIP"
blocked_vip = vip_users & blocked_users
print(f"Blocked VIPs: {blocked_vip}")
# Find "all users who need notification (VIPs + blocked)"
notify_users = vip_users | blocked_users
print(f"Users to notify: {notify_users}")
Output:
Normal users: {'Alice', 'Charlie'}
Active VIPs: {'Bob', 'Eve'}
Blocked VIPs: {'Diana'}
Users to notify: {'Bob', 'Diana', 'Eve'}
Common Use Cases
- Configuration management: Store config parameters (key=setting name, value=setting value); use
get()with defaults. - Frequency counting: Use dict as a counter —
dict[key] = dict.get(key, 0) + 1for each occurrence. - Data grouping: Nested dicts
{"department": [employee_list]}for grouping by department. - Deduplication: Set auto-removes duplicates;
list(set(data))for quick dedup (no order);dict.fromkeys(data)for dedup with order. - Permission checks: Set operations for intersection (overlapping permissions) and difference (missing permissions).
❓ FAQ
discard() and remove()? A: remove() raises KeyError if the element doesn't exist. discard() doesn't — it removes if present, or silently does nothing if not. If you're unsure whether an element exists, use discard() for safety.📖 Summary
- Dictionaries use
{}, store key-value pairs, and look up values by key quickly - Basic operations:
dict[key]read/write,get()safe read,deldelete - Common methods:
keys(),values(),items()for iteration;pop()remove and return;update()merge setdefault()returns existing value or inserts a default- Dictionary values can be any type, including lists and dicts — enabling nested structures
- Sets use
{}orset(), unique and unordered, mainly for deduplication and math operations - Set operations:
&intersection,|union,-difference,^symmetric difference
📝 Exercises
-
Basic (Difficulty ⭐): Create a dictionary for your personal info (name, age, city, hobby). Use
get()to read a "job" field (return "not filled" if missing). Useitems()to output all key-value pairs. -
Intermediate (Difficulty ⭐⭐): Given the sentence
"hello world hello python world hello", count the occurrences of each word and find the most frequent word. Hint: Use a dictionary for counting; usemax(dict.items(), key=lambda x: x[1])to find the max. -
Challenge (Difficulty ⭐⭐⭐): Write a "Simple Contact Book" program. Use a dictionary (name → phone number). Support:
add Alice 13800138000,del Alice,find Alice,all(list all). Usewhile True;exitto quit. Hint: Usesplit()to parse commands.



