In this tutorial, you’ll learn the basics of Python sets and the various set methods you can use to modify Python sets. 

Sets are one of the built-in data structures in Python. When you need to work with a non-repeating collection of elements, you’ll use the set as the go-to data structure.

Over the following several sections, we’ll go over the basics of python sets and the set methods you can use to work with them. We will then learn how to perform common set operations in Python.

Let’s begin!

Basics of Python Sets

In Python, a set is an unordered collection of non-repeating elements. This means the elements in a set should all be distinct.

You can add and remove elements from a set; therefore, the set is a mutable collection. It can contain elements of different data types. However, the individual elements in a set should be hashable.

In Python, an object is said to be hashable if its hash value never changes. Most immutable objects such as Python strings, tuples, and dictionaries are hashable.

We’ll learn about creating sets in detail. For now, consider the following two sets:

py_set = {0,1,2,(2,3,4),'Cool!'}
py_set = {0,1,2,[2,3,4],'Oops!'}

# Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-40-2d3716c7fe01> in <module>()
----> 1 py_set = {0,1,2,[2,3,4],'Oops!'}

TypeError: unhashable type: 'list'

The first set contains three numbers, a tuple, and a string. The set initialization runs without error. Whereas the second set contains a list instead of a tuple. A list is a mutable collection, it cannot be hashed, and the initialization throws a TypeError.

📑 Putting it all together, we can define a Python set as a mutable collection of distinct and hashable elements.

How to Create a Python Set

We’ll start by learning how to create a set in Python. 

#1. Using Explicit Initialization

You can create a set in Python by specifying the elements of the set, separated by commas (,) and enclosed in a pair of curly braces {}.

py_set1 = {'Python','C','C++','JavaScript'}
type(py_set1)

# Output
set

If you’ve worked with Python lists before, you know that [] initializes an empty list. Even though a Python set is enclosed in a pair of curly braces {}, you cannot use a pair {} to initialize a set. This is because {} it initializes a Python dictionary and not a Python set.

py_set2 = {}
type(py_set2)

# Output
dict

You can again call the type() function to verify that py_set it is a dictionary (dict).

#2. Using the set() Function

If you’d like to initialize an empty set and then add elements to it, you can do so using the set() function.

py_set3 = set()
type(py_set3)

# Output
set

#3. Casting Other Iterables into a Set

Another way to create sets is to cast other iterables, such as lists and tuples, into sets, using set(iterable).

py_list = ['Python','C','C++','JavaScript','C']
py_set4 = set(py_list)
print(py_set4)
# {'C++', 'C', 'JavaScript', 'Python'} # repeating element 'C' removed
type(py_set4)
# set

In the above example, py_list contains ‘C’ twice. But in py_set4, ‘C’ appears only once, as the set is a collection of distinct elements. This technique of casting into the set is often used to remove duplicates from Python lists.

How to Add Elements to a Python Set

Let’s start by creating an empty set py_set and work with it for the remainder of this tutorial.

py_set = set()
len(py_set) # returns the length of a set
# Output
0

#1. Using the .add() Method

To add elements to a set, you can use the .add() method. set.add(element) adds element to the set.

For clarity, we’ll add elements to the Python set and print out the set at each step.

▶️ Let’s add the string ‘Python’ as an element to py_set.

py_set.add('Python')
print(py_set)

# Output
{'Python'}

Next, we’ll add another element.

py_set.add('C++')
print(py_set)

# Output
{'Python', 'C++'}

It’s important to understand that the .add() method only adds an element to the set if it is not already present. If the set already contains the element you’d like to add, the add operation has no effect.

To verify this, let’s try adding ‘C++’ to py_set.

py_set.add('C++')
print(py_set)

# Output
{'Python', 'C++'}

The set contains ‘C++’, so the add operation has no effect.

▶️ Let’s add a few more elements to the set.

py_set.add('C')
print(py_set)
py_set.add('JavaScript')
print(py_set)
py_set.add('Rust')
print(py_set)

# Output
{'Python', 'C++', 'C'}
{'JavaScript', 'Python', 'C++', 'C'}
{'Rust', 'JavaScript', 'Python', 'C++', 'C'}

#2. Using the .update() Method

So far, we’ve seen how to add elements to the existing set – one element at a time.

What if you’d like to add more than one element to a sequence of elements?

You can do so using the .update() method with the syntax: set.update(collection) to add elements in collection to a set. The collection can be a list, tuple, dictionary, and so on.

py_set.update(['Julia','Ruby','Scala','Java'])
print(py_set)

# Output
{'C', 'C++', 'Java', 'JavaScript', 'Julia', 'Python', 'Ruby', 'Rust', 'Scala'}

This method is helpful when you want to add a collection of elements to a set without creating another object in memory.

 In the next section, let’s learn how to remove elements from a set.

How to Remove Elements from a Python Set

Let’s consider the following set (py_set before the update operation).

py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'}

#1. Using the .pop() Method

set.pop() removes an element randomly from the set and returns it. Let’s call the pop method on py_set and see what it returns.

py_set.pop()

# Output
'Rust'

This time, the call to .pop()  method returned the string ‘Rust’.

Note: Because the .pop() method returns an element at random, when you run the code at your end, you might as well get another element.

When we examine the set, ‘Rust’ is no longer present in the set.

print(py_set)

# Output
{'JavaScript', 'Python', 'C++', 'C'}

#2. Using the .remove() and discard() Methods

In practice, you may want to remove specific elements from the set. To do this, you can use the .remove() and .discard() methods.

set.remove(element) removes elements from the set.

py_set.remove('C')
print(py_set)

# Output
{'JavaScript', 'Python', 'C++'}

If we try to remove an element not present in the set, we’ll run into a KeyError.

py_set.remove('Scala')

# Output
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-58-a1abab3a8892> in <module>()
----> 1 py_set.remove('Scala')

KeyError: 'Scala'

Let’s take a look at py_set it again. We now have three elements.

print(py_set)

# Output
{'JavaScript', 'Python', 'C++'}

With the syntax set.discard(element), the .discard() method also removes elements from the set.

py_set.discard('C++')
print(py_set)

# Output
{'JavaScript', 'Python'}

However, it differs from the .remove() method in that it does not raise a KeyError when we try to remove an element that is not present. 

If we try to remove ‘Scala’ (which does not exist) from the list using the .discard() method, we see no error.

py_set.discard('Scala') #no error!
print(py_set)

# Output
{'JavaScript', 'Python'}

How to Access Elements of a Python Set

So far, we’ve learned how to add and remove elements from Python sets. However, we haven’t yet seen how to access individual elements in a set.

As a set is an unordered collection, it is not indexable. Therefore, if you try to access the elements of a set using the index, you’ll run into an error, as shown.

py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'}

print(py_set[0])

# Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-27-0329274f4580> in <module>()
----> 1 print(py_set[0])

TypeError: 'set' object is not subscriptable

So how do you access elements in a set?

There are two common ways to do this:

  • Loop through the set and access each element 
  • Check if a particular element is a member of the set

▶️ Loop through the set and access elements using a for loop.

for elt in py_set:
  print(elt)

# Output
C++
JavaScript
Python
Rust
C

In practice, you may want to check if a given element is present in the set using the in operator.

Note: element in set returns True if element is present in set; else it returns False.

In this example, py_set contains ‘C++’ and does not contain’ Julia’ and the in operator returns True and False, respectively.

'C++' in py_set
# True
'Julia' in py_set
# False

How to Find the Length of a Python Set

As seen earlier, you can use the len() function to get the number of elements present in a set.

py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'}
len(py_set)

# Output: 5

How to Clear a Python Set

To clear a set by removing all elements, you can use the .clear() method.

Let’s call the .clear() method on py_set

py_set.clear()

If you try to print it out, you will get set() – indicating that the set is empty. You can also call the len() function to verify that the length of the set is zero.

print(py_set)
# set()
print(len(py_set))
# 0

So far, we’ve learned how to perform basic CRUD operations on Python sets:

  • Create: Using set() function, type casting, and initialization
  • Read: Access elements of the set using loops and in operator for membership testing
  • Update: Add, remove elements from sets, and update sets
  • Delete: Clear a set by removing all elements from it

Common Set Operations, Explained with Python Code

Python sets also allow us to perform the basic set operations. We’ll learn about them in this section.

#1. Union of Sets in Python

In set theory, the union of two sets is the set of all elements in at least one of the two sets. If there are two sets, A and B, then the union contains elements that are present only in A, only in B, and the elements present in both A and B.

To find the union of sets, you can use the | operator or the .union() the method with the syntax: setA.union(setB).

setA = {1,3,5,7,9}
setB = {2,4,6,8,9}

print(setA | setB)
# Output
{1, 2, 3, 4, 5, 6, 7, 8, 9}

setA.union(setB)

# Output
{1, 2, 3, 4, 5, 6, 7, 8, 9}

Set union is a commutative operation; so A U B is the same as B U A. Let’s verify this by interchanging the positions of setA and setB in the .union() method call.

setB.union(setA)

# Output
{1, 2, 3, 4, 5, 6, 7, 8, 9}

#2. Intersection of Sets in Python

Another joint set operation is this intersection of two sets, A and B. Set intersection operation returns a set that contains all the elements present in both A and B.

To compute the intersection, you can use the & operator or the .intersection() method, as explained in the code snippet below.

print(setA & setB)

# Output
{9}

setA.intersection(setB)

# Output
{9}

In this example, element 9 is present in both setA and setB; so the intersection set contains only this element.

Like the set union, the set intersection is also a commutative operation.

setB.intersection(setA)

# Output
{9}

#3. Set Difference in Python

Given any two sets, union and intersection help us find the elements present in both and at least one of the sets, respectively. On the other hand, set difference helps us find the elements present in one set but not in the other.

python-set-difference

setA.difference(setB) gives the set of elements that are present only in setA and not in setB.

setB.difference(setA) gives the set of elements that are present only in setB and not in setA.

print(setA - setB)

print(setB - setA)

# Output
{1, 3, 5, 7}
{8, 2, 4, 6}

Clearly, A\B is not the same as B\A, so the set difference is not a commutative operation.

setA.difference(setB)
# {1, 3, 5, 7}

setB.difference(setA)
# {2, 4, 6, 8}

#4. Symmetric Set Difference in Python

While set intersection gives us elements present in both sets, the symmetric set difference returns the set of elements present in exactly one of the sets.

Consider the following example.

setA = {1,3,5,7,10,12}
setB = {2,4,6,8,10,12}

To compute the symmetric difference set, you can use the ^ operator or the .symmetric_difference() method.

print(setA ^ setB)

# Output
{1, 2, 3, 4, 5, 6, 7, 8}

The elements 10 and 12 are present in both setA and setB. So they are not present in the symmetric difference set.

setA.symmetric_difference(setB)

# Output
{1, 2, 3, 4, 5, 6, 7, 8}

As the symmetric set difference operation collects all elements that appear in exactly one of the two sets, the resultant set is the same regardless of the order in which the elements are collected. Therefore, a symmetric set difference is a commutative operation.

setB.symmetric_difference(setA)

# Output
{1, 2, 3, 4, 5, 6, 7, 8}

#5. Subsets and Supersets in Python

In set theory, subsets and supersets help understand the relationship between two sets. 

Given two sets A and B, set B is a subset of set A if all elements in set B are also present in set A. And set A is the superset of set B.

Consider the example of two sets: languages and languages_extended.

languages = {'Python', 'JavaScript','C','C++'}
languages_extended = {'Python', 'JavaScript','C','C++','Rust','Go','Scala'}

In Python, you can use the .issubset() method to check if a given set is a subset of another set.

setA.issubset(setB) returns True if setA is a subset of setB; else, it returns False.

In this example, languages is a subset of languages_extended.

languages.issubset(languages_extended)
# Output
True

Similarly, you can use the .issuperset() method to check if a given set is a superset of another set.

setA.issuperset(setB) returns True if setA is a superset of setB; else, it returns False.

languages_extended.issuperset(languages)
# Output
True

As languages_extended is a superset of languages, languages_extended.issuperset(languages) returns True, as seen above.

Conclusion

I hope this tutorial helped you understand the working of Python sets, the set methods for CRUD operations, and common set operations. As a next step, you can try using them in your Python projects.

You can check out other in-depth Python guides. Happy learning!