PythonMastery
reference 5 min read · lesson 5 of 16 in Reference

Python Set Operations Cheat Sheet

1 · The lesson

read

Unordered collection of unique, hashable items. O(1) membership tests. Supports mathematical set algebra. For the full tutorial, see Sets.


Creating

python
a = {1, 2, 3}                       # set literal
b = set()                           # EMPTY set — NOT {}
c = set([1, 2, 2, 3])               # {1, 2, 3} — dedups
d = set("hello")                    # {'h','e','l','o'}
e = {x for x in range(5)}           # comprehension
f = frozenset([1, 2, 3])            # immutable, hashable

# {} is an EMPTY DICT, not an empty set
type({})       # <class 'dict'>
type(set())    # <class 'set'>

Adding & Removing

MethodBehaviour
.add(x)Add single item
.update(iter)Add all from iterable (or another set)
.remove(x)Remove, raises KeyError if missing
.discard(x)Remove if present, no error
.pop()Remove & return arbitrary item, KeyError if empty
.clear()Empty the set
python
s = {1, 2}
s.add(3)              # {1, 2, 3}
s.update([4, 5])      # {1, 2, 3, 4, 5}
s.update({6}, [7])    # multiple iterables OK
s.remove(99)          # KeyError
s.discard(99)         # silent
s.pop()               # arbitrary item

Membership

python
1 in {1, 2, 3}              # True       O(1)
4 not in {1, 2, 3}          # True

Sets shine when you need fast in tests. Converting a list to a set first is often the win:

python
allowed = set(allowed_list)
[x for x in xs if x in allowed]    # O(n), not O(n*m)
+ setup added so this can run · defines allowed_list, xs
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

allowed_list = _AutoMock('allowed_list')
xs = ["alpha", "beta", "gamma"]

Set Algebra

OperatorMethodMeaning
a \| ba.union(b)All items in either
a & ba.intersection(b)Items in both
a - ba.difference(b)In a but not b
a ^ ba.symmetric_difference(b)In exactly one
python
a = {1, 2, 3}
b = {2, 3, 4}

a | b       # {1, 2, 3, 4}
a & b       # {2, 3}
a - b       # {1}
b - a       # {4}
a ^ b       # {1, 4}

Operators (|, &, -, ^) require both sides to be sets. Methods (.union(...), etc.) accept any iterable:

python
{1, 2}.union([3, 4], (5,))      # {1, 2, 3, 4, 5}
{1, 2} | [3, 4]                 # TypeError

In-place Algebra

python
a |= b      # a.update(b)                  union
a &= b      # a.intersection_update(b)     intersect
a -= b      # a.difference_update(b)       subtract
a ^= b      # a.symmetric_difference_update(b)
+ setup added so this can run · defines a, b
a = 1
b = 1

Comparisons

OpMethodMeaning
a <= ba.issubset(b)Every elem of a in b
a < b—Proper subset (a <= b and a != b)
a >= ba.issuperset(b)Every elem of b in a
a > b—Proper superset
a == b—Same elements
a.isdisjoint(b)—No overlap
python
{1, 2} <= {1, 2, 3}     # True
{1, 2} < {1, 2}         # False (not proper)
{1, 2}.isdisjoint({3, 4})  # True

Comprehensions

python
{x * 2 for x in range(5)}
{x for x in words if len(x) > 3}
{x.lower() for x in names}
+ setup added so this can run · defines words, names
words = ["alpha", "beta", "gamma"]
names = ["alpha", "beta", "gamma"]

Common Patterns

python
# Dedup a list (order NOT preserved)
list(set(xs))

# Dedup preserving order (use dict, not set)
list(dict.fromkeys(xs))

# Common items between two lists
set(a) & set(b)

# Items in A not in B
set(a) - set(b)

# Items unique to either side
set(a) ^ set(b)

# Fast lookup table
banned = {"foo", "bar", "baz"}
clean = [w for w in words if w not in banned]

# Count unique
len(set(xs))

# All unique?
len(xs) == len(set(xs))

# frozenset as dict key (sets aren't hashable, frozensets are)
groups = {frozenset({1, 2}): "pair_a"}
+ setup added so this can run · defines xs, a, b, words
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

xs = _AutoMock('xs')
a = _AutoMock('a')
b = _AutoMock('b')
words = ["alpha", "beta", "gamma"]

Common Errors

ErrorCauseFix
TypeError: unhashable type: 'list'Adding list/dict/set to a setConvert to tuple or frozenset
{} is dict not setEmpty {} creates a dictUse set() for empty set
KeyError on .remove(x)Item not in setUse .discard(x) instead
TypeError: unsupported operand type(s) for &Mixing set and list with &Convert: s & set(lst), or use s.intersection(lst)
Order seems randomSets are unorderedUse sorted(s) if you need order
AttributeError: 'frozenset' object has no attribute 'add'frozensets are immutableUse set if you need to mutate

See Also

Practice this

on practicepython.in

Short exercises that run in your browser and tell you what your code actually did, not just whether a test passed.