Python’s `S.symmetric_difference(T)`

method creates and returns a new set containing all elements that are in exactly one of the two sets `S`

and `T`

.

Here’s a minimal example where we return a new set containing the elements 1 and 4 that are in exactly one of the two sets `s`

and `t`

.

>>> s = {1, 2, 3} >>> t = {2, 3, 4} >>> s.symmetric_difference(t) {1, 4}

Here’s another visual example from Harry Potter: there are good wizards, bad wizards, and wizards that are both. The symmetric difference between those two sets consists of all wizards that are either good or bad, but not both—like Professor Snape.

>>> good = {'ron', 'harry', 'hermione', 'dumbledore', 'snape'} >>> bad = {'grindewald', 'voldemort', 'malfoy', 'snape'} >>> good.symmetric_difference(bad) {'ron', 'hermione', 'dumbledore', 'harry', 'grindewald', 'voldemort', 'malfoy'}

## Syntax

Let’s dive into the formal syntax of the `set.symmetric_difference()`

method.

set.symmetric_difference(set)

Argument | Data Type | Explanation |
---|---|---|

`set` | A set | The set that should be used as a basis for the symmetric difference computation |

## Return Value of set.symmetric_difference()

The return value of `set_1.symmetric_difference(set_2)`

is a new set containing all elements that are in exactly one of the two sets.

## Python Set Symmetric Difference ^ Operator

? A much more concise way to write the set symmetric difference is the overloaded “hat” operator

. When applied to two sets **"^"**`s`

and `t`

, the result of `s ^ t`

is the same as calling `s.symmetric_difference(t)`

. It computes the symmetric difference of all elements in the original set except the elements in the second set.

Here’s a basic example:

>>> s = {1, 2, 3} >>> t = {2, 3, 4} >>> s.symmetric_difference(t) {1, 4} >>> s ^ t {1, 4}

You can see that this “hat” notation is more concise and more readable at the same time. Therefore, it is recommended to use the

operator over the **^**`set.symmetric_difference()`

method.

You don’t need to import any library to use the symmetric difference operator—it is built-in.

## Advanced Examples Set Symmetric Difference

There are some subtleties you need to understand regarding the set difference function. Let’s dive into them by example!

The straightforward example is to calculate the symmetric difference of a set with another subset:

>>> {1, 2, 3}.symmetric_difference({1}) {2, 3}

But what if you’d invert this and calculate the symmetric difference between a subset and a superset? In this case, the result is the same set as before that contains the elements that are in exactly one of the two sets.

>>> {1}.symmetric_difference({1, 2, 3}) {2, 3}

Can you compute the symmetric difference between a set and an empty set? Sure! The return value is the original set, copied.

>>> {1, 2, 3}.symmetric_difference(set()) {1, 2, 3}

## Set symmetric_difference() vs symmetric_difference_update()

The `set.symmetric_difference()`

method returns a new set whereas the `set.symmetric_difference_update()`

operates on the set it is called upon and returns `None`

.

`s.symmetric_difference(t)`

– Return a new set with elements in either this set or the specified set argument, but not elements that are members of both.`s.`

– Replace this set with the symmetric difference, i.e., elements in either this set or the specified set argument, but not elements that are members of both.`symmetric_`

difference_update(t)

Here’s an example that shows the symmetric difference method:

>>> s = {1, 2, 3} >>> t = s.symmetric_difference({1, 2}) >>> s {3}

And the `set.symmetric_difference_update()`

updates on an existing set `s`

and doesn’t return anything:

>>> s = {1, 2, 3} >>> s.symmetric_difference_update({1, 2}) >>> s {3}

## What is the Time Complexity of set.symmetric_difference()?

The runtime complexity of the `set.symmetric_difference()`

function on a set with ** n** elements and a set argument with

**elements is**

*m***because you need to check for each element in both sets whether it is a member of the other set. Checking membership is**

*O(m+n)***, so the runtime complexity is**

*O(1)***.**

*O(n) * O(1) + O(m) * O(1) = O(n+m)*You can see this in the following simple experiment where we run the set method multiple times for increasing set sizes:

I ran this experiment on my ** Acer Aspire 5 notebook** (I know) with

**(8th Gen) processor and 16GB of memory. Here’s the code of the experiment:**

*Intel Core i7*import matplotlib.pyplot as plt import random import time sizes = [i * 10**5 for i in range(50)] runtimes = [] for size in sizes: s = set(range(size)) t = set(range(0, size, 2)) # Start track time ... t1 = time.time() s.symmetric_difference(t) t2 = time.time() # ... end track time runtimes.append(t2-t1) plt.plot(sizes, runtimes) plt.ylabel('Runtime (s)') plt.xlabel('Set Size') plt.show()

## Other Python Set Methods

All set methods are called on a given set. For example, if you created a set `s = {1, 2, 3}`

, you’d call `s.clear()`

to remove all elements of the set. We use the term ** “this set”** to refer to the set on which the method is executed.

`add()` | Add an element to this set |

`clear()` | Remove all elements from this set |

`copy()` | Create and return a flat copy of this set |

`difference()` | Create and return a new set containing all elements of this set except the ones in the given set arguments. The resulting set has at most as many elements as any other. |

`difference_update()` | Remove all elements from this set that are members of any of the given set arguments. |

`discard()` | Remove an element from this set if it is a member, otherwise do nothing. |

`intersection()` | Create and return a new set that contains all elements that are members of all sets: this and the specified as well. . |

`intersection_update()` | Removes all elements from this set that are not members in all other specified sets. |

`isdisjoint()` | Return `True` if no element from this set is a member of any other specified set. Sets are disjoint if and only if their intersection is the empty set. |

`issubset()` | Return `True` if all elements of this set are members of the specified set argument. |

`issuperset()` | Return `True` if all elements of the specified set argument are members of this set. |

`pop()` | Remove and return a random element from this set. If the set is empty, it’ll raise a `KeyError` . |

`remove()` | Remove and return a specific element from this set as defined in the argument. If the set doesn’t contain the element, it’ll raise a `KeyError` . |

`symmetric_difference()` | Return a new set with elements in either this set or the specified set argument, but not elements that are members of both. |

`symmetric_difference_update()` | Replace this set with the symmetric difference, i.e., elements in either this set or the specified set argument, but not elements that are members of both. |

`union()` | Create and return a new set with all elements that are in this set, or in any of the specified set arguments. |

`update()` | Update this set with all elements that are in this set, or in any of the specified set arguments. The resulting set has at least as many elements as any other. |

While working as a researcher in distributed systems, Dr. Christian Mayer found his love for teaching computer science students.

To help students reach higher levels of Python success, he founded the programming education website Finxter.com. He’s author of the popular programming book Python One-Liners (NoStarch 2020), coauthor of the Coffee Break Python series of self-published books, computer science enthusiast, freelancer, and owner of one of the top 10 largest Python blogs worldwide.

His passions are writing, reading, and coding. But his greatest passion is to serve aspiring coders through Finxter and help them to boost their skills. You can join his free email academy here.