Python Set Methods Cheat Sheet
A complete reference for Python set operations, operators, patterns, and performance characteristics.
🌟Creating Sets
Ways to initialize and construct sets in Python.
{} creates an empty dict, not a set. Use set() for an empty set.
# Empty dict, NOT a set! empty_dict = {} type(empty_dict) # <class 'dict'> # Correct way to create an empty set empty_set = set() type(empty_set) # <class 'set'>
Constructor to create a set. Without arguments, creates an empty set.
s = set() print(s) # set()
Create a set from any iterable: list, tuple, string, range, etc. Duplicates are removed.
set([1, 2, 2, 3]) # {1, 2, 3} set(("a", "b", "a")) # {'a', 'b'} set("hello") # {'h', 'e', 'l', 'o'} set(range(5)) # {0, 1, 2, 3, 4}
Set comprehension: concise way to build sets from iterables with optional filtering.
{x**2 for x in range(10)}
# {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
{x for x in "abracadabra" if x not in "abc"}
# {'r', 'd'}
Immutable set constructor. Once created, elements cannot be added or removed.
fs = frozenset([1, 2, 3]) print(fs) # frozenset({1, 2, 3}) # frozenset is hashable d = {fs: "immutable key"}
➕Adding & Removing
Methods that modify the set in-place.
Add a single element to the set. If the element already exists, the set remains unchanged.
s = {1, 2, 3} s.add(4) print(s) # {1, 2, 3, 4} s.add(2) # Already exists, no error print(s) # {1, 2, 3, 4}
Add multiple elements from an iterable (or another set). Equivalent to in-place union.
s = {1, 2} s.update([3, 4, 4]) print(s) # {1, 2, 3, 4} # Operator equivalent s |= {5, 6} print(s) # {1, 2, 3, 4, 5, 6}
Remove an element. Raises KeyError if the element is not in the set.
s = {1, 2, 3} s.remove(2) print(s) # {1, 3} s.remove(99) # KeyError: 99
Remove an element if present. Does not raise an error if the element is missing.
s = {1, 2, 3} s.discard(2) print(s) # {1, 3} s.discard(99) # No error, set unchanged
Remove and return an arbitrary element. Raises KeyError if the set is empty.
s = {1, 2, 3} elem = s.pop() print(elem) # arbitrary: 1, 2, or 3 print(s) # remaining 2 elements set().pop() # KeyError: 'pop from an empty set'
📈Set Operations — New Sets
Methods and operators that return a new set without modifying the original.
Return a new set with elements from both sets (all unique elements).
a = {1, 2, 3} b = {3, 4, 5} a.union(b) # {1, 2, 3, 4, 5} a | b # {1, 2, 3, 4, 5} a.union(b, {6}) # {1, 2, 3, 4, 5, 6}
Return a new set with elements common to both sets.
a = {1, 2, 3} b = {2, 3, 4} a.intersection(b) # {2, 3} a & b # {2, 3}
Return a new set with elements in s but not in other.
a = {1, 2, 3} b = {2, 3, 4} a.difference(b) # {1} a - b # {1} # Note: not commutative b - a # {4}
Return a new set with elements in either set, but not in both (XOR).
a = {1, 2, 3} b = {2, 3, 4} a.symmetric_difference(b) # {1, 4} a ^ b # {1, 4}
Return True if the sets have no elements in common.
a = {1, 2} b = {3, 4} c = {2, 5} a.isdisjoint(b) # True a.isdisjoint(c) # False
🔧Set Operations — In-Place
Modify the set directly instead of returning a new one.
Update the set, keeping only elements found in both.
s = {1, 2, 3, 4} s.intersection_update({3, 4, 5}) print(s) # {3, 4} # Operator equivalent s &= {3, 5} print(s) # {3}
Update the set, removing elements found in the other.
s = {1, 2, 3, 4} s.difference_update({3, 4, 5}) print(s) # {1, 2} # Operator equivalent s -= {1} print(s) # {2}
Update the set, keeping only elements in either set, but not both.
s = {1, 2, 3} s.symmetric_difference_update({2, 3, 4}) print(s) # {1, 4} # Operator equivalent s ^= {1, 5} print(s) # {4, 5}
In-place union operator. Equivalent to s.update(other).
s = {1, 2} s |= {2, 3, 4} print(s) # {1, 2, 3, 4} # Also works with any iterable s |= [5, 6] print(s) # {1, 2, 3, 4, 5, 6}
🔍Querying & Inspecting
Check membership, size, and relationships between sets.
Return the number of elements in the set.
s = {1, 2, 3, 3} len(s) # 3 (duplicates removed) empty = set() len(empty) # 0
Test membership. Average time complexity is O(1) due to hash table.
s = {"apple", "banana", "cherry"} "apple" in s # True "grape" not in s # True 42 in s # False
Return True if every element of s is in other.
{1, 2}.issubset({1, 2, 3}) # True
{1, 2} <= {1, 2, 3} # True
# Every set is a subset of itself
{1, 2} <= {1, 2} # True
Return True if every element of other is in s.
{1, 2, 3}.issuperset({1, 2}) # True
{1, 2, 3} >= {1, 2} # True
# Every set is a superset of itself
{1, 2} >= {1, 2} # True
Proper superset / proper subset. True only if strict containment (not equal).
{1, 2, 3} > {1, 2} # True (proper superset)
{1, 2} < {1, 2, 3} # True (proper subset)
# Not proper if equal
{1, 2} > {1, 2} # False
{1, 2} < {1, 2} # False
📋Copying & Clearing
Duplicate or empty a set safely.
Return a shallow copy of the set. Equivalent to set(s).
s = {1, 2, 3} c = s.copy() c.add(4) print(s) # {1, 2, 3} — original unchanged print(c) # {1, 2, 3, 4}
Remove all elements from the set. The set becomes empty.
s = {1, 2, 3} s.clear() print(s) # set() print(len(s)) # 0
Use the copy module for shallow or deep copies (useful with nested mutable elements).
import copy s = {(1, 2), (3, 4)} shallow = copy.copy(s) deep = copy.deepcopy(s) # For flat sets of immutable items, all three are equivalent
⚡Set Comprehensions
Concise, expressive syntax for building sets.
Transform each element from an iterable into a new set.
squares = {x**2 for x in range(10)} print(squares) # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81} chars = {c.upper() for c in "hello"} # {'H', 'E', 'L', 'O'}
Filter elements while building the set.
items = [-2, -1, 0, 1, 2, 3] positives = {x for x in items if x > 0} print(positives) # {1, 2, 3} evens = {x for x in range(20) if x % 2 == 0} # {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
Flatten nested structures using multiple for clauses.
matrix = [[1, 2], [3, 4], [2, 5]] flat = {x for sublist in matrix for x in sublist} print(flat) # {1, 2, 3, 4, 5} # Equivalent nested loop result = set() for sublist in matrix: for x in sublist: result.add(x)
🔒Frozenset Methods
Immutable sets: hashable, usable as dict keys and set elements.
All read-only and set-operation methods work on frozenset.
fs = frozenset([1, 2, 3]) fs.union({3, 4}) # frozenset({1, 2, 3, 4}) fs.intersection({2, 3}) # frozenset({2, 3}) fs.issubset({1, 2, 3, 4}) # True fs.isdisjoint({4, 5}) # True len(fs) # 3 2 in fs # True
Any method or operator that modifies the set is forbidden on frozenset.
fs = frozenset([1, 2]) # All of these raise AttributeError: # fs.add(3) # fs.remove(1) # fs.update({3}) # fs.pop() # fs.clear() # fs |= {3} # fs &= {1} # fs -= {1} # fs ^= {1}
Because frozenset is hashable, it can be an element of another set or a dict key.
# A set of sets is impossible with mutable sets # But works with frozenset: set_of_sets = { frozenset([1, 2]), frozenset([2, 3]), } # As dictionary keys cache = { frozenset(["a", "b"]): 42 }
💡Common Patterns
Practical recipes for everyday Python development.
Fastest way to remove duplicates. Note: order is lost.
items = [1, 2, 2, 3, 3, 3] unique = list(set(items)) print(unique) # [1, 2, 3] (order may vary)
Use dict.fromkeys() to keep the first occurrence of each element (Python 3.7+).
items = [3, 1, 2, 1, 3, 2] ordered = list(dict.fromkeys(items)) print(ordered) # [3, 1, 2]
Use set difference to find items present in one list but not the other.
a = [1, 2, 3, 4] b = [3, 4, 5, 6] # In a but not in b list(set(a) - set(b)) # [1, 2] # In b but not in a list(set(b) - set(a)) # [5, 6]
Quickly count distinct values in any iterable.
words = ["apple", "banana", "apple", "cherry", "banana"] count = len(set(words)) print(count) # 3 # Unique characters in a string len(set("abracadabra")) # 5
Track seen items with a set for O(1) lookup while filtering iterables.
items = [1, 2, 1, 3, 2, 4, 1] seen = set() result = [] for x in items: if x not in seen: seen.add(x) result.append(x) print(result) # [1, 2, 3, 4]
📊Method vs Operator Comparison
Quick reference for choosing between method and operator syntax.
Union: union() vs | vs update() vs |=
| Method | Returns | Mutates? | Syntax Example | When to Use |
|---|---|---|---|---|
s.union(other) | New set | No | a.union(b, c) | Multiple iterables, keep original |
s | other | New set | No | a | b | c | Chaining, readability |
s.update(other) | None | Yes | s.update([1,2]) | Modify in-place, any iterable |
s |= other | None | Yes | s |= {1, 2} | Concise in-place update |
Intersection: intersection() vs & vs intersection_update() vs &=
| Method | Returns | Mutates? | Syntax Example | When to Use |
|---|---|---|---|---|
s.intersection(other) | New set | No | a.intersection(b, c) | Multiple iterables, keep original |
s & other | New set | No | a & b & c | Chaining, readability |
s.intersection_update(other) | None | Yes | s.intersection_update(b) | Modify in-place |
s &= other | None | Yes | s &= b | Concise in-place filter |
Difference: difference() vs - vs difference_update() vs -=
| Method | Returns | Mutates? | Syntax Example | When to Use |
|---|---|---|---|---|
s.difference(other) | New set | No | a.difference(b, c) | Multiple exclusions, keep original |
s - other | New set | No | a - b - c | Chaining exclusions |
s.difference_update(other) | None | Yes | s.difference_update(b) | Remove elements in-place |
s -= other | None | Yes | s -= b | Concise in-place removal |
Symmetric Difference: symmetric_difference() vs ^ vs symmetric_difference_update() vs ^=
| Method | Returns | Mutates? | Syntax Example | When to Use |
|---|---|---|---|---|
s.symmetric_difference(other) | New set | No | a.symmetric_difference(b) | Keep original, get XOR result |
s ^ other | New set | No | a ^ b | Readability, expression context |
s.symmetric_difference_update(other) | None | Yes | s.symmetric_difference_update(b) | In-place XOR update |
s ^= other | None | Yes | s ^= b | Concise in-place XOR |
⏱Performance Complexity
Time and space complexity for common set operations.
| Operation | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
s.add(x) | O(1) average | O(1) | Amortized; worst case O(n) on resize |
s.remove(x) | O(1) average | O(1) | Raises KeyError if missing |
s.discard(x) | O(1) average | O(1) | No error if missing |
s.pop() | O(1) average | O(1) | Arbitrary element removed |
a | b (union) | O(len(a) + len(b)) | O(len(a) + len(b)) | Scales with total elements |
a & b (intersection) | O(min(len(a), len(b))) | O(min(len(a), len(b))) | Iterates over the smaller set |
a - b (difference) | O(len(a)) | O(len(a)) | Iterates over a, checks b |
a ^ b (symmetric diff) | O(len(a) + len(b)) | O(len(a) + len(b)) | Union of two differences |
x in s | O(1) average | O(1) | Hash table lookup |
len(s) | O(1) | O(1) | Stored internally |
s.copy() | O(n) | O(n) | Shallow copy of all elements |
s.clear() | O(1) | O(1) | Clears internal table |
🌟Pro Tips
Wisdom from the field to write better set code.
x in s on a set is O(1) average case. On a list it is O(n). For large collections and frequent lookups, always prefer sets.discard() unless you specifically want KeyError as control flow. It makes code cleaner and avoids unnecessary exception handling.frozenset when you need a set as a dictionary key or as an element of another set. It has all the non-mutating methods of a regular set.{} creates an empty dictionary. This is a common beginner mistake. Always use set() for empty sets.for loops with .add(). They also keep variable scope cleaner.