Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Sets in Python
Perhaps you recall learning about sets and set theory at some point in your mathematical education. Maybe you even remember Venn diagrams:

If this doesn’t ring a bell, don’t worry! This tutorial should still be easily accessible for you.
In mathematics, a rigorous definition of a set can be abstract and difficult to grasp. Practically though, a set can be thought of simply as a well-defined collection of distinct objects, typically called elements or members.
Grouping objects into a set can be useful in programming as well, and Python provides a built-in set type to do so. Sets are distinguished from other object types by the unique operations that can be performed on them.
Here’s what you’ll learn in this tutorial: You’ll see how to define set objects in Python and discover the operations that they support. As with the earlier tutorials on lists and dictionaries, when you are finished with this tutorial, you should have a good feel for when a set is an appropriate choice. You will also learn about frozen sets, which are similar to sets except for one important detail.
Take the Quiz: Test your knowledge with our interactive “Python Sets” quiz. Upon completion you will receive a score so you can track your learning progress over time:
Defining a Set
Python’s built-in set type has the following characteristics:
- Sets are unordered.
- Set elements are unique. Duplicate elements are not allowed.
- A set itself may be modified, but the elements contained in the set must be of an immutable type.
Let’s see what all that means, and how you can work with sets in Python.
A set can be created in two ways. First, you can define a set with the built-in set() function:
x = set(<iter>)
In this case, the argument <iter> is an iterable—again, for the moment, think list or tuple—that generates the list of objects to be included in the set. This is analogous to the <iter> argument given to the .extend() list method:
>>> x = set(['foo', 'bar', 'baz', 'foo', 'qux'])
>>> x
{'qux', 'foo', 'bar', 'baz'}
>>> x = set(('foo', 'bar', 'baz', 'foo', 'qux'))
>>> x
{'qux', 'foo', 'bar', 'baz'}
Strings are also iterable, so a string can be passed to set() as well. You have already seen that list(s) generates a list of the characters in the string s. Similarly, set(s) generates a set of the characters in s:
>>> s = 'quux'
>>> list(s)
['q', 'u', 'u', 'x']
>>> set(s)
{'x', 'u', 'q'}
You can see that the resulting sets are unordered: the original order, as specified in the definition, is not necessarily preserved. Additionally, duplicate values are only represented in the set once, as with the string 'foo' in the first two examples and the letter 'u' in the third.
Alternately, a set can be defined with curly braces ({}):
x = {<obj>, <obj>, ..., <obj>}
When a set is defined this way, each <obj> becomes a distinct element of the set, even if it is an iterable. This behavior is similar to that of the .append() list method.
Thus, the sets shown above can also be defined like this:
>>> x = {'foo', 'bar', 'baz', 'foo', 'qux'}
>>> x
{'qux', 'foo', 'bar', 'baz'}
>>> x = {'q', 'u', 'u', 'x'}
>>> x
{'x', 'q', 'u'}
To recap:
- The argument to
set()is an iterable. It generates a list of elements to be placed into the set. - The objects in curly braces are placed into the set intact, even if they are iterable.
Observe the difference between these two set definitions:
>>> {'foo'}
{'foo'}
>>> set('foo')
{'o', 'f'}
A set can be empty. However, recall that Python interprets empty curly braces ({}) as an empty dictionary, so the only way to define an empty set is with the set() function:
>>> x = set()
>>> type(x)
<class 'set'>
>>> x
set()
>>> x = {}
>>> type(x)
<class 'dict'>
An empty set is falsy in a Boolean context:
>>> x = set()
>>> bool(x)
False
>>> x or 1
1
>>> x and 1
set()
You might think the most intuitive sets would contain similar objects—for example, even numbers or surnames:
>>> s1 = {2, 4, 6, 8, 10}
>>> s2 = {'Smith', 'McArthur', 'Wilson', 'Johansson'}
Python does not require this, though. The elements in a set can be objects of different types:
>>> x = {42, 'foo', 3.14159, None}
>>> x
{None, 'foo', 42, 3.14159}
Don’t forget that set elements must be immutable. For example, a tuple may be included in a set:
>>> x = {42, 'foo', (1, 2, 3), 3.14159}
>>> x
{42, 'foo', 3.14159, (1, 2, 3)}
But lists and dictionaries are mutable, so they can’t be set elements:
>>> a = [1, 2, 3]
>>> {a}
Traceback (most recent call last):
File "<pyshell#70>", line 1, in <module>
{a}
TypeError: unhashable type: 'list'
>>> d = {'a': 1, 'b': 2}
>>> {d}
Traceback (most recent call last):
File "<pyshell#72>", line 1, in <module>
{d}
TypeError: unhashable type: 'dict'
Set Size and Membership
The len() function returns the number of elements in a set, and the in and not in operators can be used to test for membership:
>>> x = {'foo', 'bar', 'baz'}
>>> len(x)
3
>>> 'bar' in x
True
>>> 'qux' in x
False
Operating on a Set
Many of the operations that can be used for Python’s other composite data types don’t make sense for sets. For example, sets can’t be indexed or sliced. However, Python provides a whole host of operations on set objects that generally mimic the operations that are defined for mathematical sets.
Operators vs. Methods
Most, though not quite all, set operations in Python can be performed in two different ways: by operator or by method. Let’s take a look at how these operators and methods work, using set union as an example.
Given two sets, x1 and x2, the union of x1 and x2 is a set consisting of all elements in either set.
Consider these two sets:
x1 = {'foo',