Python Reference

Python Set Methods Cheat Sheet

A complete reference for Python set operations, operators, patterns, and performance characteristics.

45+
Methods
9
Categories
0
Dependencies

🌟Creating Sets

Ways to initialize and construct sets in Python.

{} vs set()
Built-in

{} 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'>
set()
Built-in

Constructor to create a set. Without arguments, creates an empty set.

s = set()
print(s)  # set()
set(iterable)
Built-in

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}
{x for x in ...}
Pattern

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'}
frozenset()
Built-inImmutable

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.

s.add(elem)
Mutates

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}
s.update(iterable) / s |= other
MutatesOperator

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}
s.remove(elem)
Mutates

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
s.discard(elem)
Mutates

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
s.pop()
MutatesReturns

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.

s.union(other) / s | other
Returns NewOperator

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}
s.intersection(other) / s & other
Returns NewOperator

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}
s.difference(other) / s - other
Returns NewOperator

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}
s.symmetric_difference(other) / s ^ other
Returns NewOperator

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}
s.isdisjoint(other)
Returns Bool

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.

s.intersection_update(other) / s &= other
MutatesOperator

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}
s.difference_update(other) / s -= other
MutatesOperator

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}
s.symmetric_difference_update(other) / s ^= other
MutatesOperator

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}
s |= other (update operator)
MutatesOperator

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.

len(s)
Built-inReturns

Return the number of elements in the set.

s = {1, 2, 3, 3}
len(s)  # 3 (duplicates removed)

empty = set()
len(empty)  # 0
elem in s / elem not in s
OperatorReturns Bool

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
s.issubset(other) / s <= other
Returns BoolOperator

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
s.issuperset(other) / s >= other
Returns BoolOperator

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
s > other / s < other
OperatorReturns Bool

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.

s.copy()
Returns New

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}
s.clear()
Mutates

Remove all elements from the set. The set becomes empty.

s = {1, 2, 3}
s.clear()
print(s)  # set()
print(len(s))  # 0
copy.copy(s) / copy.deepcopy(s)
Returns New

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.

Basic: {x**2 for x in range(10)}
Pattern

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'}
With condition: {x for x in items if x > 0}
Pattern

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}
Nested: flatten a matrix
Pattern

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.

Available on frozenset
Non-mutating

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
NOT available on frozenset
Mutating

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}
Use case: sets of sets
Pattern

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.

Deduplicate a list
Pattern

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)
Deduplicate preserving order
Pattern

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]
Find unique elements in one list vs another
Pattern

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]
Count unique items
Pattern

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
Remove seen elements while iterating
Pattern

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 |=

MethodReturnsMutates?Syntax ExampleWhen to Use
s.union(other)New setNoa.union(b, c)Multiple iterables, keep original
s | otherNew setNoa | b | cChaining, readability
s.update(other)NoneYess.update([1,2])Modify in-place, any iterable
s |= otherNoneYess |= {1, 2}Concise in-place update

Intersection: intersection() vs & vs intersection_update() vs &=

MethodReturnsMutates?Syntax ExampleWhen to Use
s.intersection(other)New setNoa.intersection(b, c)Multiple iterables, keep original
s & otherNew setNoa & b & cChaining, readability
s.intersection_update(other)NoneYess.intersection_update(b)Modify in-place
s &= otherNoneYess &= bConcise in-place filter

Difference: difference() vs - vs difference_update() vs -=

MethodReturnsMutates?Syntax ExampleWhen to Use
s.difference(other)New setNoa.difference(b, c)Multiple exclusions, keep original
s - otherNew setNoa - b - cChaining exclusions
s.difference_update(other)NoneYess.difference_update(b)Remove elements in-place
s -= otherNoneYess -= bConcise in-place removal

Symmetric Difference: symmetric_difference() vs ^ vs symmetric_difference_update() vs ^=

MethodReturnsMutates?Syntax ExampleWhen to Use
s.symmetric_difference(other)New setNoa.symmetric_difference(b)Keep original, get XOR result
s ^ otherNew setNoa ^ bReadability, expression context
s.symmetric_difference_update(other)NoneYess.symmetric_difference_update(b)In-place XOR update
s ^= otherNoneYess ^= bConcise in-place XOR

Performance Complexity

Time and space complexity for common set operations.

OperationTime ComplexitySpace ComplexityNotes
s.add(x)O(1) averageO(1)Amortized; worst case O(n) on resize
s.remove(x)O(1) averageO(1)Raises KeyError if missing
s.discard(x)O(1) averageO(1)No error if missing
s.pop()O(1) averageO(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 sO(1) averageO(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.

01
Sets are unordered
Never rely on element order. Iteration order is arbitrary and may change between runs (especially with string hashing randomization).
02
O(1) membership tests
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.
03
Prefer discard() over remove()
Use discard() unless you specifically want KeyError as control flow. It makes code cleaner and avoids unnecessary exception handling.
04
frozenset is hashable
Use 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.
05
Empty set is set(), not {}
{} creates an empty dictionary. This is a common beginner mistake. Always use set() for empty sets.
06
Comprehensions beat for-loops
Set comprehensions are generally faster and more readable than equivalent for loops with .add(). They also keep variable scope cleaner.