set.intersection_update()

The in-place intersection — keep the overlap with the given iterable(s). Everything not shared is removed.

Set methodPython 2.6+Live demo
Common call
seen.intersection_update(allowed)
Returns
None — set is mutated to the shared subset
Replaces
a manual `s = s & other` reassignment
Watch out
accepts any iterable; multiple iterables narrow the set further (AND together)
set.intersection_update(*others)
None

Demo

Live evaluation
Try:
Inputs
setsetexisting elements
othersetitems to keep (iterable)
Output
{'1', '2', '3', '4'}.intersection_update({'2', '3', '5'})
[]

intersection_update mutates the set in place. Real Python returns None; the demo shows the RESULTING state so the effect is visible. Every element that is NOT in the iterable is removed from the set. When the other iterable is empty, the set becomes empty. The iterable can be any iterable, not just another set.

Parameters

NameTypeRequiredDescription
*othersiterableno (())Zero or more iterables. The set is narrowed to elements found in ALL of them. With zero args the set is unchanged.

Return value

NoneReturns None. The set is mutated in place — keeps only elements that appear in the set AND in every given iterable. Equivalent to `s &= set(other1) & set(other2) & ...` but takes any iterables, not just sets.

Common patterns

Narrow to an allowlist
Keep only the elements that match a given whitelist.
active.intersection_update(allowed_ids)
Multiple filters at once
Chain multiple iterables — the result is the intersection of ALL.
candidates.intersection_update(available, in_budget, matches_criteria)
The operator alternative
`&=` is equivalent when the RHS is a set. intersection_update is more flexible.
s &= other_set                     # requires a set
s.intersection_update(iterable)     # any iterable
Progressive narrowing
Start with the widest set, then apply filters step by step.
candidates = set(all_users)
candidates.intersection_update(paying_users)
candidates.intersection_update(active_users)

Examples

1. Basic
s = {1, 2, 3, 4} s.intersection_update([2, 3]) s
Returns
{2, 3}
2. Partial overlap
{"a", "b", "c"}.intersection_update({"c", "d"})
Returns
{"c"}
3. No overlap gives empty
{1, 2}.intersection_update({3, 4})
Returns
set()
4. Empty other gives empty
{1, 2}.intersection_update([])
Returns
set()
5. Multiple iterables
s.intersection_update([1, 2, 3], [2, 3, 4])
Returns
{2, 3} # AND together
6. Returns None
{1, 2}.intersection_update([1])
Returns
None

Pitfalls

1. intersection_update() returns None — do NOT assign the result
Same rule as every mutation. Assigning the result sets your variable to None.
Assigned None
s = s.intersection_update(other)
s is now None
Just call it
s.intersection_update(other)
s is the narrowed set
2. Empty iterable ⇒ empty set
An empty other means "keep only elements in nothing" — which is nothing. The set becomes empty. Sometimes surprising if you thought empty meant "no filter".
Assumed no-op
{"a", "b"}.intersection_update([])
set()
Guard if needed
if other:
    s.intersection_update(other)
no change on empty
3. Multiple iterables narrow FURTHER — they AND together
Passing two iterables keeps only elements in the set AND in both. Not "in either" — that would be a union.
Assumed OR
set.intersection_update([1,2], [3,4])   # each restricts
set() unless something in all three
Union for OR
s.intersection_update(set(iterable1) | set(iterable2))
items in either
4. A string is a sequence of characters
Passing a string treats each CHARACTER as a candidate to keep. Wrap in a list if you meant to keep just the string itself.
Broken into chars
s = {"hi", "h"}
s.intersection_update("hi")
{"h"} # kept the char, dropped "hi"
Wrap it
s.intersection_update(["hi"])
{"hi"} # kept the string

When to use

Use it
  • Narrowing a set to an allowlist
  • Progressive filtering through multiple constraints
  • Building a "kept" state from a candidate pool
  • In-place refinement without allocating a new set
Reach for something else
  • You need a new set — use `&` or `intersection()` for a pure result
  • You want elements in either — use `|` or union
  • Empty iterable should NOT clear the set → guard first
  • Non-hashable elements → filter or convert to tuples first

Notes

Complexity
O(min(m, n)) — proportional to the smaller of set and iterable size
Return
None; the set is mutated in place
CPython impl
Objects/setobject.c :: set_intersection_update
Memory
Usually shrinks; hash table capacity may be reduced
Thread-safe
Not safe under concurrent iteration or mutation

FAQ

For a set on the right, they are equivalent: `s &= t` calls `s.intersection_update(t)`. But intersection_update accepts ANY iterable (list, string, generator) and multiple iterables in one call. `&=` requires a set on the right.

History

2.6
intersection_update() supports multiple *args of iterables.
2.3
set added as a builtin type with intersection_update().