set.symmetric_difference()

Elements unique to one side or the other — the "xor" of set operations.

Set methodPython 2.6+Live demo
Common call
s1 ^ s2
Returns
a NEW set — self and other untouched
Replaces
`(a | b) - (a & b)` in one call
Watch out
takes EXACTLY ONE other — no variadic form (unlike union/intersection/difference)
set.symmetric_difference(otherotherA single iterable — set, list, tuple, generator, string, dict (keys). Only one is accepted; symmetric difference is not defined for more than two sets in this method.type: iterable · required)
set

Demo

Live evaluation
Try:
Inputs
asetfirst set (comma-separated)
bsetsecond set (comma-separated)
Output
{'1', '2', '3', '4'}.symmetric_difference({'3', '4', '5', '6'})
TypeError: 'object' object is not iterable

symmetric_difference returns a NEW set — self is untouched. An element is kept only if it appears in EXACTLY ONE of the two inputs. Unlike union/intersection/difference, this method takes ONE other only — variadic symmetric difference is not defined at the method level. Order shown is not meaningful; Python sets are unordered.

Parameters

NameTypeRequiredDescription
otheriterableyesA single iterable — set, list, tuple, generator, string, dict (keys). Only one is accepted; symmetric difference is not defined for more than two sets in this method.

Return value

setA NEW set of elements that appear in EITHER self OR other, but NOT in both — the exclusive-or of two sets. Commutative: swapping the arguments gives the same result.

Common patterns

"What changed" between two sets
The operator form reads like "a xor b".
changes = old_tags ^ new_tags
Diff two configurations
Show keys that appear in one config but not the other.
diff_keys = cfg_a.keys() ^ cfg_b.keys()
Toggle set membership
XOR with a single-element set flips whether that element is in.
flags ^= {"debug"}   # add if absent, remove if present

Examples

1. Partial overlap
{1, 2, 3} ^ {2, 3, 4}
Returns
{1, 4}
2. Disjoint = union
{1, 2} ^ {3, 4}
Returns
{1, 2, 3, 4}
3. Identical = empty
{1, 2, 3} ^ {1, 2, 3}
Returns
set()
4. Iterable other
{1, 2, 3}.symmetric_difference([2, 3, 4])
Returns
{1, 4}
5. Commutative
({1, 2} ^ {2, 3}) == ({2, 3} ^ {1, 2})
Returns
True

Pitfalls

1. Takes exactly ONE other — not variadic
Unlike union, intersection, and difference (which all accept multiple iterables), symmetric_difference takes exactly one. Passing multiple raises TypeError.
Wrong shape
{1, 2}.symmetric_difference({3}, {4})
TypeError: symmetric_difference() takes exactly 2 arguments (3 given)
Chain with `^`
{1, 2} ^ {3} ^ {4}
{1, 2, 3, 4}
2. The `^` operator requires sets on both sides
symmetric_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}.symmetric_difference([2, 3])
{1}
3. symmetric_difference() is NOT the update version
symmetric_difference returns a fresh set. symmetric_difference_update mutates self in place and returns None.
Original untouched
a = {1, 2}
a.symmetric_difference({2, 3})
a
{1, 2} # unchanged
Two options
a = a ^ {2, 3}                        # new set
# or
a.symmetric_difference_update({2, 3})    # mutate
{1, 3}
4. String iterables explode into characters
Same footgun as union/intersection/difference — a string passed as "other" is iterated as characters.
Char explosion
{"Ann", "Bob"}.symmetric_difference("Bob")
{"Ann", "B", "o", "b"}
Wrap it
{"Ann", "Bob"}.symmetric_difference({"Bob"})
{"Ann"}

When to use

Use it
  • Comparing two collections for "what differs" without direction
  • Flag toggling (XOR with a singleton set)
  • Diff-style reports across two snapshots
  • Composing exclusive-or logic with other pure set operations
Reach for something else
  • You care WHICH side has the extras → use two directional differences (a - b, b - a)
  • Combining more than two sets XOR-wise → chain the `^` operator
  • You want to mutate in place → symmetric_difference_update or ^=
  • Unhashable elements → use a list comprehension

Notes

Complexity
O(|a| + |b|)
Return
A new set — same type as self (`set` or `frozenset`)
CPython impl
Objects/setobject.c :: set_symmetric_difference
Memory
Allocates a new set sized for the exclusive elements
Thread-safe
Safe against reads; not safe under concurrent writes to the input sets

FAQ

`|` (union) keeps elements in EITHER OR BOTH. `^` (symmetric_difference) keeps elements in exactly ONE — never both. Symmetric difference is a strict subset of union.

History

2.3
set type added; symmetric_difference available as `^` operator.
2.6
symmetric_difference() method accepts any iterable (not just sets).