Sets in Python | Python Course | Dataplexa

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)
Languages: {'Go', 'Java', 'C++', 'Python'} Total unique: 4 Original list: [85, 90, 85, 78, 90, 92, 78] After removing duplicates: {85, 90, 92, 78}
  • 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)
Type of {}: <class 'dict'> Type of set(): <class 'set'> Set after adding: {'Python', 'Data Science'}

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)
After add: {'Math', 'Science', 'English', 'History'} After remove: {'Math', 'Science', 'History'} After discard: {'Math', 'Science', 'History'}
  • Use discard() in most cases — it is safer than remove() 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.")
'editor' has access. '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 students): {'Amit', 'Priya', 'Kiran', 'Sneha', 'Rahul', 'Arjun', 'Meera'} Intersection (in both): {'Priya', 'Sneha', 'Rahul'} Difference (only Python): {'Amit', 'Kiran'} Symmetric diff (one only): {'Amit', 'Kiran', 'Arjun', 'Meera'}
  • | — 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))
union() : {'Amit', 'Priya', 'Kiran', 'Sneha', 'Arjun', 'Meera'} intersection() : {'Priya', 'Sneha'} difference() : {'Amit', 'Kiran'} symmetric_difference : {'Amit', 'Kiran', 'Arjun', 'Meera'}

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))
Candidate A qualified: True Candidate B qualified: False Candidate A has all required: True No shared animals: True

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)
Before: {'Python', 'SQL', 'Git'} After update(): {'Python', 'SQL', 'Git', 'Docker', 'Django'} After intersection_update(): {'Python', 'SQL', 'Docker'} After difference_update(): {'Python', 'Docker'}

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)
Original list: ['python', 'coding', 'python', 'tutorial', 'coding', 'beginner'] After set(): {'coding', 'python', 'tutorial', 'beginner'} Sorted unique list: ['beginner', 'coding', 'python', 'tutorial'] As tuple: ('coding', 'python', 'tutorial', 'beginner')

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])
Frozenset: frozenset({'read', 'write', 'execute'}) Has read access: True Error: 'frozenset' object has no attribute 'add' Your role: editor

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))
In both warehouses : {'Mouse', 'Keyboard', 'Webcam'} Only in Warehouse A : {'Laptop', 'Monitor'} Only in Warehouse B : {'Headphones', 'Desk Lamp'} All unique products : {'Laptop', 'Mouse', 'Keyboard', 'Monitor', 'Webcam', 'Headphones', 'Desk Lamp'} Total unique count : 7

Quick Reference Table

ConceptSyntaxWhat It Does
Create sets = {1, 2, 3}Unordered, unique items only
Empty sets = set()Must use set() — not {}
From listset([1,2,2,3])Removes duplicates automatically
Adds.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 sFast True/False check
Uniona | bAll items from both sets
Intersectiona & bItems in BOTH sets
Differencea - bItems in a but NOT in b
Symmetric diffa ^ bItems in one but NOT both
Subset checka.issubset(b)True if all of a is inside b
Superset checka.issuperset(b)True if a contains all of b
Disjoint checka.isdisjoint(b)True if no items shared
Frozensetfrozenset({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}?





NEXT UP
Type Casting in Python
Learn how to convert values between different data types — integers, floats, strings, booleans, lists, tuples, and sets.