All you need to know about Python sets
In Python, a set is an unordered collection of unique elements.
Inspired by mathematical sets, it's an extremely powerful tool for managing data without duplicates, making quick comparisons, or filtering efficiently.
Some typical uses:
- Remove duplicates from a list;
- Check if two lists have common elements;
- Manage groups, tags, permissions, etc.
Think of a set as a bag of objects where each object appears only once, no matter how many times you put it in.
What is a set in Python?
Simply put, a set is:
- Unordered: elements don't follow a specific position;
- Mutable: you can add/remove elements without problems;
- Composed only of immutable objects: for example, numbers, strings, tuples, but not lists or other sets.
Let's take an example to illustrate all this! 😋
my_set = {1, 2, 3, 4}
print(my_set) # {1, 2, 3, 4}
If we add a duplicate, it will be automatically removed to keep only one element:
my_set = {1, 2, 2, 3}
print(my_set) # {1, 2, 3}
Python automatically eliminates repetitions.
Warning: sets don't guarantee any display order. The same set may appear differently from one call to another.
Creating a set
There are several ways to create a set in Python.
With curly braces
The first way to create a set in Python is to use curly braces.
animals = {"cat", "dog", "bird"}
Easy, right? 👀
With the set() function
It's also possible to use a dedicated function to create sets: set()
.
fruits = set(["apple", "banana", "apple"])
print(fruits) # {'apple', 'banana'}
Be careful when creating empty sets! You must use the
set()
function.PYTHON# Wrong: creates an empty dictionary a = {} # Right: creates an empty set a = set()
Accessing elements in a set
Sets have the particularity of not being indexed: you can't directly access an element by its position like with a list.
animals = {"cat", "dog", "rabbit"}
# animals[0] ERROR!
We must therefore use another way... A loop would be quite appropriate!
for animal in animals:
print(animal)
Even if the order of appearance is unpredictable, each element will be traversed exactly once.
Adding and removing elements
Adding an element with add()
It's possible to add an element to our set using the method dedicated to this instruction: add()
.
animals = {"cat", "dog"}
animals.add("bird")
print(animals) # {'cat', 'dog', 'bird'}
Removing an element
To remove an element, we have a bit more choice:
remove(element)
: raises an error if the element doesn't exist;discard(element)
: does nothing if the element doesn't exist;pop()
: removes a random element (very useful in games).
Let's take an example.
animals.remove("dog")
animals.discard("cat")
removed = animals.pop()
Prefer
discard()
if you're not sure the element exists, to avoid errors. 😉
Completely clearing a set
We can also decide to clear a set using the clear()
method.
animals.clear()
Checking for element presence in a set
Often we want to check that an element is present in our set.
To do this, we can use the in
keyword. Its purpose is to return true
or false
depending on whether the element on the left is in the set on the right.
"dog" in {"dog", "cat"} # ✅ True
"rabbit" in {"dog", "cat"} # ❌ False
Operations on sets
Sets allow you to directly perform mathematical set operations.
Union (with "|" or "union()")
A union allows you to combine all elements from set A
and set B
.
To do this, we can use both the pipe (|
) or the union()
method.
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b) # {1, 2, 3, 4, 5}
print(a.union(b)) # same
Intersection (with "&" or "intersection()")
Like with unions, it's possible to do intersections to display only elements present in both A
and set B
.
Two possibilities as well:
- Use the
&
operator; - Use the
intersection()
method.
a = {1, 2, 3}
b = {3, 4, 5}
print(a & b) # {3}
print(a.intersection(b)) # same
Difference (with "-" or "difference()")
The opposite of an intersection, a difference allows you to display/use only elements that are neither in A
nor in set B
.
Same, two possibilities:
- Use the
-
operator; - Use the
difference()
method.
a = {1, 2, 3}
b = {3, 4, 5}
print(a - b) # {1, 2}
print(a.difference(b)) # same
Symmetric difference (with "^" or "symmetric_difference()")
Finally we can calculate a symmetric difference using the ^
operator or the symmetric_difference()
method.
A symmetric difference is nothing more than a way to retrieve elements present in A
and elements present in set B
but not in both simultaneously.
a = {1, 2, 3}
b = {3, 4, 5}
print(a ^ b) # {1, 2, 4, 5}
print(a.symmetric_difference(b)) # same
These operations are fast and readable, perfect for filtering, merging, or excluding data.
Comparing sets
It's possible to use sets in Python to perform some comparisons.
Comparing sets allows you to know how two sets relate to each other: do they have the same elements? Does one contain the other? Are they completely distinct?
To do this, we can use several methods that we'll see together.
issubset(): subset
Checks if all elements of the current set are also in another set.
a = {1, 2}
b = {1, 2, 3}
print(a.issubset(b)) # ✅ True
print(b.issubset(a)) # ❌ False
We can imagine for example a check on minimum permissions required for a user.
issuperset(): superset
Checks if the current set contains all elements of another set.
a = {1, 2}
b = {1, 2, 3}
print(b.issuperset(a)) # ✅ True
print(a.issuperset(b)) # ❌ False
isdisjoint(): no common elements
Returns True
if the two sets are completely distinct.
x = {"cat", "dog"}
y = {"apple", "banana"}
print(x.isdisjoint(y)) # ✅ True
Making an equality comparison ("==")
Finally, two sets are equal if they contain exactly the same elements, regardless of order.
a = {1, 2, 3}
b = {3, 1, 2}
print(a == b) # ✅ True
Summary table
Let's make a small recap of the methods we've seen together to compare sets in Python.
Method | What it checks | Example |
issubset() | Is A contained in B? | Permissions |
issuperset() | Does A contain all elements of B? | Permission groups |
isdisjoint() | A and B have no common elements | Exclusive filters |
== | A and B are strictly identical | Control equalities |
Sets and performance
Sets are extremely performant for certain operations, particularly membership tests (in
) and deletions.
Remember? We talked about it just before. 😋
"Python" in ["Python", "Java", "C"] # ✅ List: O(n)
"Python" in {"Python", "Java", "C"} # ✅ Set: O(1) on average
Sets use a hashing system, which allows for nearly instantaneous search, even with large amounts of data.
Just avoid using a set if you need to preserve order.
Set vs List vs Tuple: comparison
Sets are often compared to lists or tuples. Let's make a point together on their differences.
Criterion | set | list | tuple |
Ordered? | ❌ No | ✅ Yes | ✅ Yes |
Unique elements? | ✅ Yes | ❌ No | ❌ No |
Modifiable? | ✅ Yes | ✅ Yes | ❌ No |
Fast for in ? | ✅ Yes | ❌ No | ❌ No |
Indexable? | ❌ No | ✅ Yes | ✅ Yes |
Typical use | Eliminate duplicates | Create ordered collections | Create immutable collections |
If you need uniqueness, speed, and no order, a set is often the best choice.
Frozensets
A frozenset
is simply an immutable version of set
. Once created, you can no longer add or remove elements.
fs = frozenset(["apple", "pear"])
It's used to guarantee the integrity of a set.
If you need a constant set, the frozenset
is the equivalent of a tuple
for sets.
This is therefore not possible:
fs = frozenset(["apple", "pear"])
fs.add("cabbage") # AttributeError: `frozenset` object has no attribute 'add'
Common errors with sets
Let's see together the common pitfalls to avoid with sets when starting out.
Believing that {} creates a set
We've seen this together! If you declare {}
this will create an empty dictionary, not a set. You must use set()
.
type({}) # <class 'dict'>
type(set()) # <class 'set'>
Using non-hashable types
Only hashable types can be used with sets.
set([[1, 2], [3, 4]]) # ❌ Error: lists are not hashable
set([(1, 2), (3, 4)]) # ✅ OK
As a reminder, a hashable object is an object:
- Whose value doesn't change over time;
- That has a reliable
__hash__()
function; - That can be compared (
__eq__()
).
These types are hashable for example: int
, float
, str
, bool
and tuple
.
But not these: list
, dict
, set
(because they can change).
Thinking that sets are all ordered
Something else we've seen together! 😋
a = {"z", "a", "b"}
print(a) # The order is arbitrary
For an ordered collection, use a
list
, not aset
.
Real practical cases
Here are some practical cases in real situations to understand well what sets can be used for.
Remove duplicates from a list
names = ["Alice", "Bob", "Alice"]
unique = list(set(names))
print(unique) # ['Alice', 'Bob']
Find common elements in two lists
a = ["cat", "dog", "rabbit"]
b = ["dog", "horse"]
common = set(a) & set(b)
print(common) # {'dog'}
Manage permissions
user_permissions = {"read", "write"}
required_permissions = {"read"}
if required_permissions.issubset(user_permissions):
print("Access granted")
Sets are ideal for cases where uniqueness and inclusion logic are essential.
Frequently asked questions about sets
When starting with sets it's quite common to ask questions! Here are our answers.
What's the difference between a
set
and a dictionary?
A set contains only unique values, while a dict
is a key/value association.
Can you have sets in a set?
No, because sets are non-hashable (we've seen this together). Use frozenset
instead:
ensemble = {frozenset([1, 2]), frozenset([3, 4])}
How can I learn Python?
With a good course: check out our Python course for example.