Python Sets

Master unordered collections of unique items and set operations

🎯 Understanding Sets

Sets are unordered, unindexed, and mutable collections of unique items. They are primarily used to store a collection of distinct elements and to perform mathematical set operations like union, intersection, difference, and symmetric difference.


# Creating and using sets
vowel = {"a", "e", "i", "o", "u"} # Set using curly braces
number = set([1, 2, 2, 3, 4])     # list duplicate removed
empty_set = set()                 # Empty set

print(vowel)                      # {'a','e','i','o','u'}
print(number)                     # {1, 2, 3, 4}
print(len(empty_set))             # 0
                                    
Unique
Elements
Unordered
Collection
Mutable
Structure

Creating Sets

Sets are created using curly braces {} or the set() constructor. Remember, sets do not allow duplicate values.

Empty Set, Set of Numbers, Set from List
# Creating a set using curly braces
my_set = {"apple", "banana", "cherry"}
print(f"My set: {my_set}") # Output: My set: {'cherry', 'apple', 'banana'} (order may vary)

# Creating a set with duplicate values (duplicates are automatically removed)
numbers_with_duplicates = {1, 2, 2, 3, 4, 4, 5}
print(f"Set with duplicates removed: {numbers_with_duplicates}") # Output: Set with duplicates removed: {1, 2, 3, 4, 5}

# Creating an empty set (IMPORTANT: use set() constructor, not {})
empty_set = set()
print(f"Empty set: {empty_set}, Type: {type(empty_set)}") # Output: Empty set: set(), Type: 

# Note: {} creates an empty dictionary, not an empty set
empty_dict = {}
print(f"Empty dict: {empty_dict}, Type: {type(empty_dict)}") # Output: Empty dict: {}, Type: 

# Creating a set from a list
my_list = [1, 2, 3, 2, 1]
set_from_list = set(my_list)
print(f"Set from list: {set_from_list}") # Output: Set from list: {1, 2, 3}

🔹 Adding Items to a Set

You can add single items or multiple items to a set using the add() and update() methods.

Add Single Item, Update with Multiple Items
my_set = {"apple", "banana", "cherry"}
print(f"Original set: {my_set}")

# add(): Adds a single item
my_set.add("orange")
print(f"After add('orange'): {my_set}") # Output: After add('orange'): {'cherry', 'apple', 'orange', 'banana'}

# Adding an existing item has no effect
my_set.add("apple")
print(f"After add('apple') again: {my_set}") # Output: After add('apple') again: {'cherry', 'apple', 'orange', 'banana'}

# update(iterable): Adds elements from another iterable (list, tuple, set, etc.)
fruits_to_add = ["kiwi", "mango", "apple"]
my_set.update(fruits_to_add)
print(f"After update(['kiwi', 'mango', 'apple']): {my_set}") # Output: After update(['kiwi', 'mango', 'apple']): {'cherry', 'apple', 'orange', 'banana', 'kiwi', 'mango'}

Removing Items from a Set

You can remove items using remove() , discard() , pop() , or clear() .

Remove, Discard, Pop, Clear
my_set = {"apple", "banana", "cherry", "orange", "kiwi"}
print(f"Original set: {my_set}")

# remove(item): Removes the specified item. Raises KeyError if item not found.
my_set.remove("banana")
print(f"After remove('banana'): {my_set}") # Output: After remove('banana'): {'cherry', 'apple', 'orange', 'kiwi'}

# my_set.remove("grape") # This would raise a KeyError

# discard(item): Removes the specified item. Does NOT raise an error if item not found.
my_set.discard("orange")
print(f"After discard('orange'): {my_set}") # Output: After discard('orange'): {'cherry', 'apple', 'kiwi'}

my_set.discard("grape") # No error, set remains unchanged
print(f"After discard('grape'): {my_set}") # Output: After discard('grape'): {'cherry', 'apple', 'kiwi'}

# pop(): Removes a random item (since sets are unordered)
popped_item = my_set.pop()
print(f"After pop(): {my_set}, Popped item: {popped_item}") # Output: (example) After pop(): {'apple', 'kiwi'}, Popped item: cherry

# clear(): Empties the set
my_set.clear()
print(f"After clear(): {my_set}") # Output: After clear(): set()

# del keyword: Deletes the entire set
# del my_set # This would delete the set variable itself

Set Operations (Mathematical)

Sets are powerful for performing common mathematical set operations.

Union, Intersection, Difference, Symmetric Difference
set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}
set3 = {"banana", "kiwi"}

# union() or |: Returns a new set containing all items from both sets
set_union = set1.union(set2)
print(f"Union (set1 | set2): {set_union}") # Output: Union (set1 | set2): {'cherry', 'apple', 'banana', 'google', 'microsoft'}

# intersection() or &: Returns a new set containing only the items common to both sets
set_intersection = set1.intersection(set2)
print(f"Intersection (set1 & set2): {set_intersection}") # Output: Intersection (set1 & set2): {'apple'}

# difference() or -: Returns a new set containing items only in the first set, not in the second
set_difference = set1.difference(set2)
print(f"Difference (set1 - set2): {set_difference}") # Output: Difference (set1 - set2): {'cherry', 'banana'}

# symmetric_difference() or ^: Returns a new set containing items present in either set, but not both
set_symmetric_difference = set1.symmetric_difference(set2)
print(f"Symmetric Difference (set1 ^ set2): {set_symmetric_difference}") # Output: Symmetric Difference (set1 ^ set2): {'cherry', 'banana', 'google', 'microsoft'}

# issubset(), issuperset(), isdisjoint()
print(f"set3 is subset of set1: {set3.issubset(set1)}") # Output: set3 is subset of set1: False
print(f"set1 is superset of set3: {set1.issuperset(set3)}") # Output: set1 is superset of set3: False
print(f"set1 and set3 are disjoint: {set1.isdisjoint(set3)}") # Output: set1 and set3 are disjoint: False (because 'banana' is common)

Real-World Example: Data Cleaning & Analysis

Sets are incredibly useful for tasks involving unique elements, such as finding unique visitors to a website, identifying common interests, or filtering out duplicates.

Unique Visitors and Common Interests
# Scenario 1: Unique Website Visitors
website_visits_day1 = {"userA", "userB", "userC", "userD"}
website_visits_day2 = {"userC", "userD", "userE", "userF"}

all_unique_visitors = website_visits_day1.union(website_visits_day2)
print(f"All unique visitors over two days: {all_unique_visitors}")
# Output: All unique visitors over two days: {'userA', 'userB', 'userC', 'userD', 'userE', 'userF'}

common_visitors = website_visits_day1.intersection(website_visits_day2)
print(f"Visitors who visited on both days: {common_visitors}")
# Output: Visitors who visited on both days: {'userC', 'userD'}

# Scenario 2: Common Interests
alice_interests = {"reading", "hiking", "cooking", "photography"}
bob_interests = {"hiking", "gaming", "cooking", "cycling"}
charlie_interests = {"reading", "coding", "gaming"}

shared_interests_alice_bob = alice_interests.intersection(bob_interests)
print(f"Alice and Bob's shared interests: {shared_interests_alice_bob}")
# Output: Alice and Bob's shared interests: {'cooking', 'hiking'}

unique_interests_all = alice_interests.union(bob_interests, charlie_interests)
print(f"All unique interests across all friends: {unique_interests_all}")
# Output: All unique interests across all friends: {'reading', 'hiking', 'cooking', 'photography', 'gaming', 'cycling', 'coding'}

🏋️ Practice Exercise: Course Enrollment System

You are building a system to manage student enrollments in different courses. Each course has a set of enrolled students (represented by their IDs). Use sets to perform the following operations:

  1. Find all students enrolled in at least one course.
  2. Find students enrolled in both "Math" and "Physics".
  3. Find students enrolled in "Chemistry" but not "Biology".
Solution Hint
# Define sets for each course:
# math_students = {"S001", "S002", "S003"}
# physics_students = {"S002", "S004", "S005"}
# chemistry_students = {"S001", "S005", "S006"}
# biology_students = {"S003", "S006", "S007"}

# Use set operations (union, intersection, difference) to solve the problems.

🧠 Test Your Knowledge

Which of the following is NOT a characteristic of Python sets?

What is the result of {1, 2, 3}.intersection({3, 4, 5}) ?