
Python Course
Sets in Python
A set is a collection where every item is unique — no duplicates allowed. If you try to add the same item twice, Python simply ignores the second one. Sets are also unordered, meaning Python does not guarantee items will appear in the order you added them.
Sets solve real problems that lists cannot handle cleanly. Need to eliminate duplicates from a list in one step? Find which items two groups have in common? Check which items are missing from one group but present in another? Sets do all of this in a single line of code.
Creating a Set
Sets are created using curly braces {} with items separated by commas. You can also use the set() function to create one from a list — duplicates are removed automatically.
# "Python" and "Java" appear twice — duplicates are silently removed
languages = {"Python", "Java", "Python", "C++", "Java", "Go"}
print("Languages:", languages)
print("Total unique:", len(languages))
# Create a set from a list — fastest way to remove duplicates
scores_list = [85, 90, 85, 78, 90, 92, 78]
unique_scores = set(scores_list)
print("Original list:", scores_list)
print("After removing duplicates:", unique_scores)
- The output order may differ from the input — sets are unordered.
set(list)is the fastest and cleanest way to eliminate duplicates from any list.
Creating an Empty Set — Important Rule
Writing {} with nothing inside creates an empty dictionary, not an empty set. To create an empty set, you must use set(). This is one of the most common beginner mistakes in Python.
wrong = {}
print("Type of {}:", type(wrong)) # dict — NOT a set!
correct = set()
print("Type of set():", type(correct)) # set
correct.add("Python")
correct.add("Data Science")
print("Set after adding:", correct)
Adding and Removing Items
Sets are mutable — you can add and remove items. However, since sets are unordered, you cannot access items by index. You work with items by value.
courses = {"Math", "Science", "English"}
# add() — adds one item, ignores if already present
courses.add("History")
courses.add("Math") # duplicate — silently ignored
print("After add:", courses)
# remove() — removes an item; KeyError if not found
courses.remove("English")
print("After remove:", courses)
# discard() — safer removal; no error if item missing
courses.discard("Art") # "Art" not in set — no crash
print("After discard:", courses)
- Use
discard()in most cases — it is safer thanremove()because it will not crash if the item does not exist. pop()removes a random item — do not rely on which one gets removed.
Membership Testing
Checking if an item exists in a set is extremely fast — even with millions of items. Sets use a hash table internally, so Python jumps directly to the answer instead of checking every item one by one like a list does.
allowed_users = {"admin", "editor", "moderator", "reviewer"}
username = "editor"
if username in allowed_users:
print(f"'{username}' has access.")
guest = "guest"
if guest not in allowed_users:
print(f"'{guest}' does not have access.")
- The syntax is identical to checking a list — but for large collections, set lookups are dramatically faster.
- Whenever you only need "is this item in here?" and do not need ordering or indexing, use a set.
Set Operations — Union, Intersection, Difference
This is where sets become truly powerful. You can compare two sets in a single step using mathematical operations — finding what is shared, what is unique to one group, or everything combined.
python_course = {"Amit", "Priya", "Kiran", "Sneha", "Rahul"}
data_sci_course = {"Priya", "Sneha", "Arjun", "Meera", "Rahul"}
# UNION — all students in either course (no duplicates)
all_students = python_course | data_sci_course
print("Union (all students):", all_students)
# INTERSECTION — students in BOTH courses
both = python_course & data_sci_course
print("Intersection (in both):", both)
# DIFFERENCE — students only in Python course, not Data Science
only_python = python_course - data_sci_course
print("Difference (only Python):", only_python)
# SYMMETRIC DIFFERENCE — in one course but not both
either_only = python_course ^ data_sci_course
print("Symmetric diff (one only):", either_only)
|— union: all items from both sets combined (no duplicates).&— intersection: only items present in both sets.-— difference: items in the first set that are not in the second.^— symmetric difference: items in one set or the other, but not in both.
Method Versions of the Same Operations
Each operator above has an equivalent named method. Both produce identical results — choose whichever feels more readable.
python_course = {"Amit", "Priya", "Kiran", "Sneha"}
data_sci_course = {"Priya", "Sneha", "Arjun", "Meera"}
print("union() :", python_course.union(data_sci_course))
print("intersection() :", python_course.intersection(data_sci_course))
print("difference() :", python_course.difference(data_sci_course))
print("symmetric_difference :", python_course.symmetric_difference(data_sci_course))
Subset, Superset, and Disjoint Checks
Sometimes you need to check if one set is completely contained inside another — for example, whether a candidate has all the required skills for a job.
required_skills = {"Python", "SQL", "Git"}
candidate_a = {"Python", "SQL", "Git", "Django", "Docker"}
candidate_b = {"Python", "HTML", "CSS"}
# issubset() — True if all required items exist in candidate's skills
print("Candidate A qualified:", required_skills.issubset(candidate_a))
print("Candidate B qualified:", required_skills.issubset(candidate_b))
# issuperset() — True if a set contains all items of another
print("Candidate A has all required:", candidate_a.issuperset(required_skills))
# isdisjoint() — True if two sets share NO items at all
set_a = {"cat", "dog", "bird"}
set_b = {"fish", "snake", "frog"}
print("No shared animals:", set_a.isdisjoint(set_b))
Updating a Set In-Place
The operations above always return new sets. Use the update versions when you want to modify an existing set directly instead.
my_skills = {"Python", "SQL", "Git"}
print("Before:", my_skills)
# update() — adds all items from another set in-place (like union)
new_skills = {"Docker", "Django", "Python"}
my_skills.update(new_skills)
print("After update():", my_skills)
# intersection_update() — keeps only items in both sets (in-place)
team_skills = {"Python", "SQL", "Docker"}
my_skills.intersection_update(team_skills)
print("After intersection_update():", my_skills)
# difference_update() — removes items found in another set (in-place)
to_remove = {"SQL"}
my_skills.difference_update(to_remove)
print("After difference_update():", my_skills)
Converting Between Set, List, and Tuple
The most common pattern: convert a list to a set to remove duplicates, then convert back to a sorted list.
raw_tags = ["python", "coding", "python", "tutorial", "coding", "beginner"]
print("Original list:", raw_tags)
# Remove duplicates
unique_tags = set(raw_tags)
print("After set():", unique_tags)
# Sort and convert back to list
sorted_tags = sorted(list(unique_tags))
print("Sorted unique list:", sorted_tags)
# Freeze as a tuple (immutable)
frozen = tuple(unique_tags)
print("As tuple:", frozen)
Frozenset — An Immutable Set
A frozenset works like a set but cannot be changed after creation. Because it is immutable, it can be used as a dictionary key — something regular sets cannot do.
permissions = frozenset({"read", "write", "execute"})
print("Frozenset:", permissions)
print("Has read access:", "read" in permissions)
# Trying to add raises AttributeError
try:
permissions.add("delete")
except AttributeError as e:
print("Error:", e)
# Frozensets as dictionary keys
role_permissions = {
frozenset({"read"}) : "viewer",
frozenset({"read", "write"}) : "editor",
frozenset({"read", "write", "execute"}): "admin"
}
my_access = frozenset({"read", "write"})
print("Your role:", role_permissions[my_access])
Real World Example — Inventory Comparison
Four real business questions answered in four lines using set operations — no loops, no complex conditionals.
warehouse_a = {"Laptop", "Mouse", "Keyboard", "Monitor", "Webcam"}
warehouse_b = {"Mouse", "Keyboard", "Headphones", "Webcam", "Desk Lamp"}
common = warehouse_a & warehouse_b
only_a = warehouse_a - warehouse_b
only_b = warehouse_b - warehouse_a
all_products = warehouse_a | warehouse_b
print("In both warehouses :", common)
print("Only in Warehouse A :", only_a)
print("Only in Warehouse B :", only_b)
print("All unique products :", all_products)
print("Total unique count :", len(all_products))
Quick Reference Table
| Concept | Syntax | What It Does |
|---|---|---|
| Create set | s = {1, 2, 3} | Unordered, unique items only |
| Empty set | s = set() | Must use set() — not {} |
| From list | set([1,2,2,3]) | Removes duplicates automatically |
| Add | s.add("x") | Adds one item; ignores duplicates |
| Remove (strict) | s.remove("x") | KeyError if item missing |
| Remove (safe) | s.discard("x") | No error if item missing |
| Membership | "x" in s | Fast True/False check |
| Union | a | b | All items from both sets |
| Intersection | a & b | Items in BOTH sets |
| Difference | a - b | Items in a but NOT in b |
| Symmetric diff | a ^ b | Items in one but NOT both |
| Subset check | a.issubset(b) | True if all of a is inside b |
| Superset check | a.issuperset(b) | True if a contains all of b |
| Disjoint check | a.isdisjoint(b) | True if no items shared |
| Frozenset | frozenset({1,2}) | Immutable set; usable as dict key |
Practice
What is the correct way to create an empty set in Python?
Which method removes an item from a set without raising an error if the item is not found?
Which operator finds items that exist in BOTH sets?
What type of set is immutable and can be used as a dictionary key?
Sets are __________, meaning you cannot rely on items appearing in a specific sequence.
Quick Quiz
What is the output of set([1, 2, 2, 3, 3, 3])?
What error does s.remove("x") raise if "x" is not in the set?
What is the result of {1, 2, 3} & {2, 3, 4}?
What does {1, 2}.issubset({1, 2, 3, 4}) return?
What is the result of {1, 2, 3} ^ {2, 3, 4}?