set.symmetric_difference()
Elements unique to one side or the other — the "xor" of set operations.
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(otherother — A 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
| Name | Type | Required | Description |
|---|---|---|---|
| other | iterable | yes | A 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
set — A 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
TruePitfalls
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).