09 - Sets and Dictionaries
A simple picture
A set is like a classroom attendance list where each name appears only once. A dictionary is like a row of labelled lockers: a unique key such as a student ID opens the value stored for that student.
key "S001" -> {"name": "Meera", "marks": 86}
Sets
A set stores unique values and is useful for membership tests and set operations. Sets do not provide index-based access.
tags = {"python", "beginner", "python"}
print(tags) # duplicate is stored once
An empty set is created with set(), not {}; {} creates an empty dictionary.
Important fact: sets remove duplicates and do not support position indexes. Do not depend on a set’s display order.
tags.add("programming")
tags.discard("unknown") # safe if missing
add() inserts one value. discard() removes a value when present and does nothing when it is absent. remove() also removes a value, but raises KeyError when the value is absent.
subjects = {"Math", "Science"}
subjects.add("Python")
subjects.discard("History")
print("Python" in subjects) # True
print(len(subjects)) # 3
Set operations
Set operations compare groups:
backend = {"python", "sql", "git"}
data = {"python", "pandas", "sql"}
print(backend & data) # intersection
print(backend | data) # union
print(backend - data) # only in backend
Using the sets above:
- intersection
backend & datakeeps values in both sets:python,sql; - union
backend | datacombines all unique values; - difference
backend - datakeeps values found only inbackend; - symmetric difference
backend ^ datakeeps values found in exactly one set.
intersection: values shared by A and B
union: every unique value from A or B
difference: values in A but not B
Use these operations to compare permissions, skills, categories, or attendance lists.
Dictionaries
A dictionary maps a key to a value:
student = {"name": "Meera", "marks": 86}
print(student["name"])
student["passed"] = True
student["marks"] = 91
Read one entry as key: value:
"name": "Meera"
key value
A key should be stable and unique inside that dictionary. Strings, numbers, and suitable tuples are common keys. Lists cannot be dictionary keys because lists can change.
Keys must be unique. Assigning an existing key updates its value. Accessing a missing key with [] raises KeyError; .get() is safer when absence is expected:
email = student.get("email", "Not provided")
Important fact:
student["email"]means “this key must exist.”student.get("email")means “this key may be missing.” Choose the form that matches the rule of your program.
Dictionary methods
Dictionary views let us inspect keys, values, or complete key-value pairs:
print(student.keys())
print(student.values())
for key, value in student.items():
print(key, value)
Use del student["passed"] or student.pop("passed") to remove an entry.
| Operation | Meaning |
|---|---|
dictionary.keys() |
view the keys |
dictionary.values() |
view the values |
dictionary.items() |
view (key, value) pairs |
dictionary.get(key, default) |
safely read an optional key |
dictionary.update(other) |
add or replace several entries |
dictionary.pop(key) |
remove and return one value |
Nested data
Nested data means one collection contains another collection:
students = {
"S001": {"name": "Meera", "marks": 86},
"S002": {"name": "Ravi", "marks": 92},
}
print(students["S002"]["marks"])
Follow one key at a time:
students
-> "S002"
-> student dictionary
-> "marks"
-> 92
Nested dictionaries model real records, but use functions to keep access logic readable.
Comprehensions
A dictionary comprehension builds key-value pairs from a loop. Read the ordinary loop first:
prices = {"pen": 10, "book": 50}
with_tax = {}
for name, price in prices.items():
with_tax[name] = price * 1.18
The shorter comprehension is:
prices = {"pen": 10, "book": 50}
with_tax = {name: price * 1.18 for name, price in prices.items()}
Use the longer loop when the rule needs several steps or explanations.
Real-world example: inventory
inventory = {"pen": 12, "book": 3}
item = "book"
quantity = 2
if inventory.get(item, 0) >= quantity:
inventory[item] -= quantity
print("Sale completed")
else:
print("Not enough stock")
Common mistakes
- Trying to index a set.
- Creating an empty set with
{}. - Assuming dictionary keys are duplicated.
- Accessing a possibly missing key with
[]instead of.get(). - Mutating a dictionary while iterating over it without a plan.
Bug Hunter
Bug 1 — empty set or dictionary?
tags = {}
tags.add("python")
Bug 2 — missing key
student = {"name": "Maya"}
print(student["email"])
Bug 3 — duplicate dictionary key
scores = {"Maya": 80, "Maya": 95}
print(scores)
A dictionary keeps one value for each unique key. The later assignment replaces the earlier value.
Show Bug Hunter fixes
# Bug 1
tags = set()
tags.add("python")
# Bug 2: use a default when absence is expected.
print(student.get("email", "Not provided"))
# Bug 3: use unique student IDs when names may repeat.
scores = {"S001": 80, "S002": 95}
Optional deeper look: why are lookups fast?
Sets and dictionaries use a structure called a hash table. Python calculates a hash from a key to find a likely storage position, then checks equality. Lookup is usually very fast—average constant time—but keys must have stable hash behavior. Immutable values such as strings, numbers, and suitable tuples can be keys; a mutable list cannot.
Practice
Try these problems on this page. Before choosing a collection, decide whether you need order, uniqueness, or key-based lookup.
Problems
- Remove duplicate values from a list using a set.
- Find common values in two lists.
- Find values present in one set but not another.
- Count character frequency using a dictionary.
- Count word frequency in a sentence.
- Find the product with the highest price.
- Merge two dictionaries and handle duplicate keys.
- Build a phone book with add and lookup operations.
- Group names by their first letter.
- Build a shopping cart dictionary and calculate its total.
Show hints
- Convert the list to a set.
- Use set intersection.
- Use set difference.
- Increase a dictionary count for each character.
- Normalize and split the sentence first.
- Iterate over dictionary items.
- Decide which dictionary wins when a key appears twice.
- Use names as keys and phone numbers as values.
- Use the first character as the group key.
- Look up each product price and multiply by its quantity.
Show solution ideas
unique_values = set(values).set(first) & set(second).set(first) - set(second).counts[ch] = counts.get(ch, 0) + 1.- Use the same pattern for words from
sentence.split(). - Start with no highest product, loop over
.items(), and remember the highest price seen so far. - Start with
merged = left.copy(), then loop throughright.items()and assign each key. This makes the right dictionary win. - Use
phone_book[name] = numberand.get()for lookup. - If the first letter is missing, create an empty list for it; then append the name.
- Add
prices[item] * quantityfor every cart entry.
Homework
Build a small inventory dictionary with product quantities. Support adding stock, selling stock, and reporting products that need restocking.
Checkpoint
Create a dictionary for three products and their prices. Calculate the total price of a selected shopping list and explain why a dictionary is useful.