Python Sets Complete Guide
Learn Python sets - creation, methods, set operations, set theory with practical examples and real-world applications for efficient unique data handling.
Unordered
No indexing
Unique
No duplicates
Set Operations
Union, Intersection
Fast Lookups
O(1) membership
What are Python Sets?
Sets are unordered collections of unique, hashable elements in Python. They are mutable, iterable, and do not allow duplicate values. Sets are ideal for membership testing, removing duplicates, and mathematical set operations.
Key Concept
Sets are unordered and contain only unique elements. They use curly braces {} or the set() constructor. Sets provide O(1) average time complexity for membership tests.
# Creating sets
empty_set = set() # Note: {} creates empty dict
numbers = {1, 2, 3, 4, 5}
vowels = {'a', 'e', 'i', 'o', 'u'}
mixed = {1, "hello", 3.14, True}
# No duplicates allowed
unique_numbers = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4}
print(unique_numbers) # {1, 2, 3, 4}
# Set from other sequences
list_to_set = set([1, 2, 3, 2, 1])
string_to_set = set("hello")
tuple_to_set = set((1, 2, 3, 2, 1))
print(f"From list: {list_to_set}") # {1, 2, 3}
print(f"From string: {string_to_set}") # {'h', 'e', 'l', 'o'}
print(f"From tuple: {tuple_to_set}") # {1, 2, 3}
# Membership testing
print(f"Is 3 in numbers? {3 in numbers}") # True
print(f"Is 10 in numbers? {10 in numbers}") # False
Python Sets Classification
Sets support various operations, methods, and set theory operations. Understanding these features helps you use sets effectively in your programs.
Complete Sets Reference Table
| Category | Syntax/Keyword | Description | Example | Output |
|---|---|---|---|---|
| Creation | {} / set() | Create empty set | s = set() |
set() |
| Creation | {1, 2, 3} | Create set with elements | s = {1, 2, 3} |
{1, 2, 3} |
| Methods | add() | Add single element | s.add(4) |
Adds 4 to set |
| Methods | remove() | Remove element (error if missing) | s.remove(3) |
Removes 3 |
| Methods | discard() | Remove element (no error) | s.discard(3) |
Removes 3 if present |
| Methods | pop() | Remove & return arbitrary element | s.pop() |
Random element |
| Methods | clear() | Remove all elements | s.clear() |
set() |
| Operations | | / union() | Union of sets | a | b |
Elements in a or b |
| Operations | & / intersection() | Intersection of sets | a & b |
Elements in both a and b |
| Operations | - / difference() | Difference of sets | a - b |
Elements in a but not b |
| Operations | ^ / symmetric_difference() | Symmetric difference | a ^ b |
Elements in a or b but not both |
| Set Theory | issubset() / <= | Check if subset | a <= b |
True/False |
| Set Theory | issuperset() / >= | Check if superset | a >= b |
True/False |
| Set Theory | isdisjoint() | Check if no common elements | a.isdisjoint(b) |
True/False |
- Sets are unordered - elements have no index
- Sets contain unique elements - duplicates automatically removed
- Sets are mutable but elements must be hashable
- Use
frozenset()for immutable sets (can be dictionary keys) - Sets provide O(1) average time for membership tests (
inoperator)
Set Examples with Output
Let's explore practical examples of set operations with actual Python code and output.
# Set Creation and Basic Methods
print("=== Set Creation ===")
# Different ways to create sets
empty_set = set() # Note: {} creates empty dict
numbers = {1, 2, 3, 4, 5}
vowels = {'a', 'e', 'i', 'o', 'u'}
mixed = {1, "hello", 3.14, True, (1, 2)} # Note: tuples are hashable
print(f"Empty set: {empty_set}")
print(f"Numbers: {numbers}")
print(f"Vowels: {vowels}")
print(f"Mixed: {mixed}")
# Sets automatically remove duplicates
with_duplicates = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4}
print(f"\nWith duplicates: {with_duplicates}") # {1, 2, 3, 4}
# From other sequences
list_to_set = set([1, 2, 3, 2, 1])
string_to_set = set("programming")
range_to_set = set(range(5))
print(f"\nFrom list: {list_to_set}") # {1, 2, 3}
print(f"From string: {string_to_set}") # {'p', 'r', 'o', 'g', 'a', 'm', 'i', 'n'}
print(f"From range: {range_to_set}") # {0, 1, 2, 3, 4}
print("\n=== Set Methods ===")
# Creating a set for demonstration
s = {1, 2, 3, 4, 5}
print(f"Original set: {s}")
# add() method
s.add(6)
s.add(2) # Adding duplicate has no effect
print(f"After add(6), add(2): {s}")
# remove() method
s.remove(3)
print(f"After remove(3): {s}")
# discard() method (safer than remove)
s.discard(4)
s.discard(99) # No error even though 99 doesn't exist
print(f"After discard(4), discard(99): {s}")
# pop() method (removes arbitrary element)
popped = s.pop()
print(f"After pop(): {s}, popped element: {popped}")
# clear() method
s.clear()
print(f"After clear(): {s}")
print("\n=== Set Operations ===")
# Recreate sets for operations
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
print(f"Set A: {a}")
print(f"Set B: {b}")
# Length of set
print(f"Length of A: {len(a)}")
print(f"Length of B: {len(b)}")
# Membership test
print(f"\nIs 3 in A? {3 in a}")
print(f"Is 9 in A? {9 in a}")
print(f"Is 4 in B? {4 in b}")
# Iterating through set
print("\nIterating through set A:")
for element in a:
print(f" Element: {element}")
# Set Operations and Methods
print("=== Set Operations ===")
# Create sets for demonstration
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
c = {2, 3, 4}
print(f"Set A: {a}")
print(f"Set B: {b}")
print(f"Set C: {c}")
# Union (| or union())
union_ab = a | b
union_method = a.union(b)
print(f"\nUnion A | B: {union_ab}")
print(f"Union using method: {union_method}")
# Multiple union
union_abc = a | b | c
print(f"Union A | B | C: {union_abc}")
# Intersection (& or intersection())
intersection_ab = a & b
intersection_method = a.intersection(b)
print(f"\nIntersection A & B: {intersection_ab}")
print(f"Intersection using method: {intersection_method}")
# Difference (- or difference())
difference_ab = a - b
difference_method = a.difference(b)
print(f"\nDifference A - B: {difference_ab}")
print(f"Difference using method: {difference_method}")
# Symmetric Difference (^ or symmetric_difference())
sym_diff_ab = a ^ b
sym_diff_method = a.symmetric_difference(b)
print(f"\nSymmetric Difference A ^ B: {sym_diff_ab}")
print(f"Symmetric Difference using method: {sym_diff_method}")
print("\n=== Update Methods ===")
# Create fresh sets
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set3 = {5, 6, 7}
print(f"Original set1: {set1}")
print(f"Original set2: {set2}")
print(f"Original set3: {set3}")
# update() - adds all elements from other sets
set1.update(set2)
print(f"After set1.update(set2): {set1}")
# intersection_update()
set1 = {1, 2, 3, 4, 5} # Reset
set1.intersection_update(set2)
print(f"After set1.intersection_update(set2): {set1}")
# difference_update()
set1 = {1, 2, 3, 4, 5} # Reset
set1.difference_update(set2)
print(f"After set1.difference_update(set2): {set1}")
# symmetric_difference_update()
set1 = {1, 2, 3, 4, 5} # Reset
set1.symmetric_difference_update(set2)
print(f"After set1.symmetric_difference_update(set2): {set1}")
# Set Theory Operations
print("=== Set Theory Operations ===")
# Create sets for demonstration
a = {1, 2, 3, 4, 5}
b = {2, 3, 4}
c = {6, 7, 8}
d = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
print(f"Set A: {a}")
print(f"Set B: {b}")
print(f"Set C: {c}")
print(f"Set D: {d}")
# Subset check (issubset() or <=)
print(f"\nSubset Checks:")
print(f"Is B subset of A? {b.issubset(a)}") # True
print(f"Is A subset of B? {a.issubset(b)}") # False
print(f"B <= A? {b <= a}") # True (same as issubset)
print(f"A <= D? {a <= d}") # True
# Proper subset check (<)
print(f"\nProper Subset Checks:")
print(f"B < A? {b < a}") # True (B is proper subset of A)
print(f"A < A? {a < a}") # False (not proper subset of itself)
print(f"A < D? {a < d}") # True
# Superset check (issuperset() or >=)
print(f"\nSuperset Checks:")
print(f"Is A superset of B? {a.issuperset(b)}") # True
print(f"Is B superset of A? {b.issuperset(a)}") # False
print(f"D >= A? {d >= a}") # True (same as issuperset)
# Proper superset check (>)
print(f"\nProper Superset Checks:")
print(f"A > B? {a > b}") # True
print(f"A > A? {a > a}") # False
print(f"D > A? {d > a}") # True
# Disjoint check (isdisjoint())
print(f"\nDisjoint Checks:")
print(f"Are A and C disjoint? {a.isdisjoint(c)}") # True
print(f"Are A and B disjoint? {a.isdisjoint(b)}") # False
print(f"Are B and C disjoint? {b.isdisjoint(c)}") # True
print("\n=== Copying Sets ===")
# Shallow copy
original = {1, 2, 3, 4, 5}
shallow_copy = original.copy()
print(f"Original: {original}")
print(f"Shallow copy: {shallow_copy}")
# Modifying copy doesn't affect original
shallow_copy.add(6)
print(f"After adding to copy:")
print(f" Original: {original}")
print(f" Copy: {shallow_copy}")
# Set comprehension
print("\n=== Set Comprehensions ===")
# Create set of squares
squares = {x**2 for x in range(10)}
print(f"Squares of 0-9: {squares}")
# Create set of even numbers
evens = {x for x in range(20) if x % 2 == 0}
print(f"Even numbers 0-19: {evens}")
# Create set from string with condition
unique_vowels = {char for char in 'hello world' if char in 'aeiou'}
print(f"Unique vowels in 'hello world': {unique_vowels}")
Set Theory Visualization
Understanding set theory operations is easier with visual representations. Here are the main set operations visualized.
Venn Diagram: Set Operations
{1, 2, 3, 4}
{3, 4, 5, 6}
{3, 4}
Union A ∪ B
A | B{1, 2, 3, 4, 5, 6}
Intersection A ∩ B
A & B{3, 4}
Difference A - B
A - B{1, 2}
Symmetric Difference
A ^ B{1, 2, 5, 6}
# Set Theory Implementation Example
print("=== Set Theory Implementation ===")
# Define sets
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
C = {2, 3, 4}
U = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} # Universal set
print(f"Set A: {A}")
print(f"Set B: {B}")
print(f"Set C: {C}")
print(f"Universal Set U: {U}")
# Basic set theory operations
print(f"\nBasic Operations:")
print(f"A ∪ B (Union): {A | B}")
print(f"A ∩ B (Intersection): {A & B}")
print(f"A - B (Difference): {A - B}")
print(f"B - A (Difference): {B - A}")
print(f"A △ B (Symmetric Difference): {A ^ B}")
# Complement (relative to universal set)
complement_A = U - A
complement_B = U - B
print(f"\nComplement of A (relative to U): {complement_A}")
print(f"Complement of B (relative to U): {complement_B}")
# De Morgan's Laws
print(f"\nDe Morgan's Laws Verification:")
# First Law: (A ∪ B)' = A' ∩ B'
left_side = U - (A | B)
right_side = (U - A) & (U - B)
print(f"(A ∪ B)' = {left_side}")
print(f"A' ∩ B' = {right_side}")
print(f"Law holds: {left_side == right_side}")
# Second Law: (A ∩ B)' = A' ∪ B'
left_side = U - (A & B)
right_side = (U - A) | (U - B)
print(f"\n(A ∩ B)' = {left_side}")
print(f"A' ∪ B' = {right_side}")
print(f"Law holds: {left_side == right_side}")
# Distributive Laws
print(f"\nDistributive Laws Verification:")
# A ∪ (B ∩ C) = (A ∪ B) ∩ (A ∪ C)
left_side = A | (B & C)
right_side = (A | B) & (A | C)
print(f"A ∪ (B ∩ C) = {left_side}")
print(f"(A ∪ B) ∩ (A ∪ C) = {right_side}")
print(f"Law holds: {left_side == right_side}")
# A ∩ (B ∪ C) = (A ∩ B) ∪ (A ∩ C)
left_side = A & (B | C)
right_side = (A & B) | (A & C)
print(f"\nA ∩ (B ∪ C) = {left_side}")
print(f"(A ∩ B) ∪ (A ∩ C) = {right_side}")
print(f"Law holds: {left_side == right_side}")
Frozen Sets
Frozen sets are immutable versions of sets. Once created, they cannot be modified, making them hashable and suitable for use as dictionary keys or elements in other sets.
# Frozen Set Examples
print("=== Frozen Sets ===")
# Creating frozen sets
fs1 = frozenset([1, 2, 3, 4, 5])
fs2 = frozenset({4, 5, 6, 7, 8})
fs3 = frozenset("hello")
print(f"Frozen set 1: {fs1}")
print(f"Frozen set 2: {fs2}")
print(f"Frozen set 3: {fs3}")
# Frozen sets support set operations (return new frozen sets)
print(f"\nSet Operations with Frozen Sets:")
print(f"Union: {fs1 | fs2}")
print(f"Intersection: {fs1 & fs2}")
print(f"Difference: {fs1 - fs2}")
print(f"Symmetric Difference: {fs1 ^ fs2}")
# Frozen sets are hashable (can be dictionary keys)
print(f"\nUsing Frozen Sets as Dictionary Keys:")
# Create dictionary with frozen set keys
configurations = {
frozenset(['server', 'database']): "Production config",
frozenset(['server', 'cache']): "Caching config",
frozenset(['database', 'cache']): "Storage config"
}
for key, value in configurations.items():
print(f" {set(key)}: {value}")
# Frozen sets can be elements in other sets
print(f"\nFrozen Sets as Set Elements:")
set_of_frozensets = {
frozenset([1, 2, 3]),
frozenset([4, 5, 6]),
frozenset([7, 8, 9])
}
print(f"Set of frozen sets: {set_of_frozensets}")
# Try to modify frozen set (will raise error)
try:
fs1.add(6) # AttributeError
print("This won't print")
except AttributeError as e:
print(f"\nCannot modify frozen set: {e}")
try:
fs1.remove(1) # AttributeError
print("This won't print")
except AttributeError as e:
print(f"Cannot remove from frozen set: {e}")
# Methods available on frozen sets
print(f"\nMethods available on frozen sets:")
print(f"fs1.issubset(fs2): {fs1.issubset(fs2)}")
print(f"fs1.issuperset(fs2): {fs1.issuperset(fs2)}")
print(f"fs1.isdisjoint(fs2): {fs1.isdisjoint(fs2)}")
print(f"Length: {len(fs1)}")
print(f"Membership: {3 in fs1}")
print(f"Iteration: ", end="")
for item in fs1:
print(item, end=" ")
- When you need immutable sets (cannot be changed after creation)
- As dictionary keys (regular sets are not hashable)
- As elements in other sets (regular sets cannot be in sets)
- When you want to ensure the set remains constant
- For configuration data, constants, or fixed collections
Sets vs Lists vs Tuples Comparison
Understanding the differences between sets, lists, and tuples helps you choose the right data structure for your needs.
| Aspect | Sets Unique | Lists Mutable | Tuples Immutable |
|---|---|---|---|
| Order | Unordered | Ordered | Ordered |
| Mutability | Mutable (except frozenset) | Mutable | Immutable |
| Duplicates | Not allowed | Allowed | Allowed |
| Indexing | Not supported | Supported (zero-based) | Supported (zero-based) |
| Syntax | {} or set() |
[] |
() |
| Hashable | No (frozenset is hashable) | No | Yes |
| Use Cases | Unique elements, membership tests, set operations | Ordered collections, stacks, queues, sequences | Immutable sequences, dictionary keys, function returns |
| Performance | O(1) for membership test | O(n) for membership test | O(n) for membership test |
- Use Sets when you need unique elements, fast membership tests, or set operations
- Use Lists when you need ordered collections that can be modified
- Use Tuples when you need immutable ordered collections or hashable sequences
- Use Frozen Sets when you need immutable sets or sets as dictionary keys
Real-World Applications
Sets are used in many practical programming scenarios. Here are common applications:
Removing Duplicates
Quickly remove duplicates from any sequence:
# Remove duplicates from list
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_numbers = list(set(numbers))
print(unique_numbers) # [1, 2, 3, 4]
# Preserve order (Python 3.7+)
from collections import OrderedDict
ordered_unique = list(OrderedDict.fromkeys(numbers))
Membership Testing
Fast O(1) membership tests:
# Fast keyword checking
keywords = {'if', 'else', 'for', 'while', 'def'}
user_input = "if x > 5: print(x)"
# Check if any keyword in input
has_keyword = any(word in keywords
for word in user_input.split())
print(f"Contains keyword: {has_keyword}")
Set Operations for Data
Find common elements, differences, etc.:
# Social media friends analysis
alice_friends = {'Bob', 'Charlie', 'Diana'}
bob_friends = {'Alice', 'Charlie', 'Eve'}
common = alice_friends & bob_friends
only_alice = alice_friends - bob_friends
all_friends = alice_friends | bob_friends
E-commerce Applications
Product categories, tags, filters:
# Product tags system
product_tags = {
'laptop': {'electronics', 'computers', 'portable'},
'book': {'education', 'entertainment'},
'headphones': {'electronics', 'audio'}
}
# Find all electronic products
electronic_products = [
product for product, tags in product_tags.items()
if 'electronics' in tags
]
Practice Exercises
Test your set skills with these exercises. Try to solve them before looking at solutions.
# Python Sets Practice Exercises
print("=== Exercise 1: Basic Set Operations ===")
# Create sets and perform basic operations
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
print(f"Set A: {A}")
print(f"Set B: {B}")
print(f"Union: {A | B}")
print(f"Intersection: {A & B}")
print(f"Difference A-B: {A - B}")
print(f"Difference B-A: {B - A}")
print(f"Symmetric Difference: {A ^ B}")
print("\n=== Exercise 2: Remove Duplicates ===")
# Remove duplicates from list using set
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
unique_numbers = list(set(numbers))
print(f"Original list: {numbers}")
print(f"Unique numbers: {unique_numbers}")
print("\n=== Exercise 3: Set Comprehensions ===")
# Create sets using comprehensions
# Squares of even numbers 0-9
even_squares = {x**2 for x in range(10) if x % 2 == 0}
print(f"Even squares 0-9: {even_squares}")
# Unique characters from string
text = "hello world python programming"
unique_chars = {char for char in text if char != ' '}
print(f"Unique chars in text: {unique_chars}")
print("\n=== Exercise 4: Set Methods ===")
# Practice set methods
s = {1, 2, 3, 4, 5}
print(f"Original set: {s}")
s.add(6)
print(f"After add(6): {s}")
s.remove(3)
print(f"After remove(3): {s}")
s.discard(10) # No error
print(f"After discard(10): {s}")
popped = s.pop()
print(f"After pop(): {s}, popped: {popped}")
print("\n=== Exercise 5: Set Theory ===")
# Verify set theory properties
U = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} # Universal set
X = {1, 2, 3, 4, 5}
Y = {4, 5, 6, 7, 8}
print(f"Universal set U: {U}")
print(f"Set X: {X}")
print(f"Set Y: {Y}")
# Complement
X_complement = U - X
Y_complement = U - Y
print(f"\nComplement of X: {X_complement}")
print(f"Complement of Y: {Y_complement}")
# De Morgan's Law: (X ∪ Y)' = X' ∩ Y'
left = U - (X | Y)
right = X_complement & Y_complement
print(f"\n(X ∪ Y)': {left}")
print(f"X' ∩ Y': {right}")
print(f"De Morgan's Law holds: {left == right}")
print("\n=== Exercise 6: Real-world Application ===")
# Course enrollment system
math_students = {'Alice', 'Bob', 'Charlie', 'Diana'}
physics_students = {'Bob', 'Diana', 'Eve', 'Frank'}
print(f"Math students: {math_students}")
print(f"Physics students: {physics_students}")
# Students in both courses
both_courses = math_students & physics_students
print(f"Students in both courses: {both_courses}")
# Students in only one course
only_one = math_students ^ physics_students
print(f"Students in only one course: {only_one}")
# All students
all_students = math_students | physics_students
print(f"All students: {all_students}")
print("\n=== Exercise 7: Frozen Sets ===")
# Create and use frozen sets
fs1 = frozenset([1, 2, 3])
fs2 = frozenset([3, 4, 5])
print(f"Frozen set 1: {fs1}")
print(f"Frozen set 2: {fs2}")
print(f"Union: {fs1 | fs2}")
print(f"Intersection: {fs1 & fs2}")
# Frozen set as dictionary key
config = {
frozenset(['debug', 'verbose']): "Development mode",
frozenset(['production', 'secure']): "Production mode"
}
print(f"\nConfigurations: {config}")
Advanced Set Techniques
Set Comprehensions
# Advanced set comprehensions
# Set of prime numbers < 50
primes = {x for x in range(2, 50)
if all(x % y != 0
for y in range(2, int(x**0.5)+1))}
print(f"Primes < 50: {primes}")
# Set of Pythagorean triples < 20
triples = {(a, b, c)
for a in range(1, 20)
for b in range(a, 20)
for c in range(b, 20)
if a*a + b*b == c*c}
print(f"Pythagorean triples: {triples}")
Symmetric Operations
# Advanced symmetric operations
# Find elements unique to each set
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
set3 = {3, 4, 5, 9, 10}
# Elements in exactly one set
unique_to_one = set1 ^ set2 ^ set3 ^ (
set1 & set2 & set3)
print(f"Unique to one set: {unique_to_one}")
# Elements in at least two sets
in_at_least_two = (
(set1 & set2) |
(set1 & set3) |
(set2 & set3))
print(f"In at least two sets: {in_at_least_two}")
Set Partitioning
# Partition sets based on conditions
numbers = set(range(1, 21))
# Partition into even and odd
even = {x for x in numbers if x % 2 == 0}
odd = {x for x in numbers if x % 2 != 0}
# Partition into multiples
multiples_of_3 = {x for x in numbers if x % 3 == 0}
multiples_of_5 = {x for x in numbers if x % 5 == 0}
print(f"Even: {even}")
print(f"Odd: {odd}")
print(f"Multiples of 3: {multiples_of_3}")
print(f"Multiples of 5: {multiples_of_5}")
Performance Optimization
# Using sets for performance
# Slow with lists (O(n) for each check)
def slow_find_common(list1, list2):
return [x for x in list1 if x in list2]
# Fast with sets (O(1) for lookup)
def fast_find_common(list1, list2):
set2 = set(list2)
return [x for x in list1 if x in set2]
# Example
large_list1 = list(range(10000))
large_list2 = list(range(5000, 15000))
# Set approach is much faster
common = fast_find_common(large_list1, large_list2)
print(f"Common elements: {len(common)}")
Key Takeaways
- Sets are unordered collections of unique elements:
{item1, item2, item3} - Use
set()for empty set (not{}which creates empty dict) - Sets automatically remove duplicates - great for deduplication
- Sets provide O(1) average time for membership tests (
inoperator) - Main set operations: Union (|), Intersection (&), Difference (-), Symmetric Difference (^)
- Set methods: add(), remove(), clear(), update(), intersection_update(), etc.
- Frozen sets (
frozenset()) are immutable and hashable (can be dictionary keys) - Set elements must be hashable - no lists or dictionaries as set elements
- Sets support set comprehensions:
{x**2 for x in range(10)} - Use sets for: removing duplicates, membership testing, mathematical set operations
- Sets are unordered - cannot index or slice them
- Set theory operations:
issubset(),issuperset(),isdisjoint() - Sets can contain mixed types but all elements must be hashable
- Sets are faster than lists/tuples for membership testing but slower for iteration