set.difference()

What is in the first set that is NOT in the others — order matters, unlike union and intersection.

Set methodPython 2.6+Live demo
Common call
s1 - s2
Returns
a NEW set — self and others untouched
Replaces
a filter with a not-in check
Watch out
not commutative — `a - b` is different from `b - a`
set.difference(*others)
set

Demo

Live evaluation
Try:
Inputs
asetfirst set (kept minus b)
bsetsecond set (subtracted from a)
Output
{'1', '2', '3', '4'}.difference({'3', '4', '5', '6'})
TypeError: 'object' object is not iterable

difference returns a NEW set — self is untouched. An element is kept only if it does NOT appear in any of the "others". Unlike union and intersection, order matters: try the "a - b vs b - a" case above, then swap the inputs and see the different result.

Parameters

NameTypeRequiredDescription
*othersiterableno (())Zero or more iterables. Any element that appears in any of them is excluded from the result. Any type: set, list, tuple, generator, string, dict (keys).

Return value

setA NEW set of elements that appear in self but not in ANY of the others. Neither self nor others are modified.

Common patterns

Remove blocked items
The operator form reads like "a WITHOUT b".
allowed = all_options - blocked
What's missing
Find items expected but not delivered.
missing = required - present
Set-based deletion
Filter a list by set membership without a per-item `in` check.
clean = list(set(items) - set(bad))

Examples

1. Basic
{1, 2, 3, 4} - {3, 4, 5}
Returns
{1, 2}
2. Iterable other
{1, 2, 3}.difference([2, 3, 4])
Returns
{1}
3. Multiple others
{1, 2, 3, 4}.difference({2}, [3])
Returns
{1, 4}
4. Disjoint returns self
{1, 2} - {3, 4}
Returns
{1, 2} # equal, not identical
5. Order matters
{1, 2} - {2, 3} # {1} {2, 3} - {1, 2} # {3}
Returns
not commutative

Pitfalls

1. The `-` operator requires sets on both sides
difference() accepts any iterable. The `-` operator does NOT — it needs a set on both sides.
Type error
{1, 2, 3} - [2, 3]
TypeError: unsupported operand type(s) for -: 'set' and 'list'
Method form
{1, 2, 3}.difference([2, 3])
{1}
2. difference() is NOT difference_update()
difference leaves both inputs alone and returns a fresh set. difference_update mutates the left one and returns None.
Original untouched
a = {1, 2, 3}
a.difference({2})
a
{1, 2, 3} # nothing removed
Two options
a = a - {2}                  # new set, replace name
# or
a.difference_update({2})       # mutate in place
{1, 3}
3. Order matters — a - b is not b - a
Union and intersection are commutative; difference is not. Getting the argument order backwards silently returns a different set.
Wrong direction
{2, 3} - {1, 2}    # expected {1}?
{3} # what is in {2,3} but not {1,2}
Swap explicitly
{1, 2} - {2, 3}
{1}
4. String iterables explode into characters
Same footgun as union and intersection — a string passed as an "other" is iterated as characters.
Char removal
{"Ann", "B", "o"}.difference("Bob")
{"Ann"} # B and o removed as CHARS
Wrap it
{"Ann", "B", "o"}.difference({"Bob"})
{"Ann", "B", "o"}

When to use

Use it
  • Filtering out members of one set from another
  • "Missing" / "extra" comparisons between expected and actual
  • Set-based access control (allowed = all - blocked)
  • Chaining with other pure set operations (|, &, -)
Reach for something else
  • You want to mutate in place → difference_update or -=
  • Two-way exclusive diff → symmetric_difference (or ^)
  • You need to preserve order → filter a list with a set membership check
  • Elements are unhashable → use list comprehension with `not in`

Notes

Complexity
O(|self| + sum(|others|)) — walks self and checks membership in each other
Return
A new set — same type as self (`set` or `frozenset`)
CPython impl
Objects/setobject.c :: set_difference
Memory
Allocates a new set sized for the leftovers
Thread-safe
Safe against reads; not safe under concurrent writes to the input sets

FAQ

They compute the same thing, but difference() accepts ANY iterable (list, tuple, generator, string). The `-` operator requires both sides to be sets. Method: flexible. Operator: strict.

History

2.3
set type added; difference available as `-` operator.
2.6
difference() method accepts multiple iterable arguments (variadic).