You are looking for the symmetric difference; all elements that appear only in set a or in set b, but not both:
a.symmetric_difference(b)
From the set.symmetric_difference()
method documentation:
Return a new set with elements in either the set or other but not both.
You can use the ^
operator too, if both a
and b
are sets:
a ^ b
while set.symmetric_difference()
takes any iterable for the other argument.
The output is the equivalent of (a | b) - (a & b)
, the union of both sets minus the intersection of both sets.
Producing the output takes O(M+N) time for sets of length M and N, respectively; M steps to copy set a
then N steps to alter that set based on each value in b
:
def symmetric_difference(a, b):
result = set(a)
for elem in b:
try:
result.remove(elem)
except KeyError:
result.add(elem)
return result
There are in-place variants too, where set a
is altered directly; use a.symmetric_difference_update(b)
or a ^= b
. The in-place variant takes O(N) time, so it depends on the size of set b
only:
def symmetric_difference_update(a, b):
for elem in b:
try:
a.remove(elem)
except KeyError:
a.add(elem)
# no return, a has been updated in-place