☰

Python Sets

Sets in Python Tutorial

Imagine you collect the email addresses of everyone who signs up for an event. Some people sign up twice, and some use the same address at different times. You want each address exactly once. Or imagine two lists of students, one for the maths club and one for the science club, and you want to know who belongs to both. A Python set is made for exactly these jobs.

A set is a collection of unique items. It throws away duplicates for you, it can tell you in an instant whether something is inside it, and it supports the operations you remember from school maths: union, intersection and difference. Sets are small, fast and very handy for cleaning data and comparing groups.

In this tutorial, we explain what a set is and how to create one, including the empty set trap that catches almost every beginner. We cover how to add and remove items, with the difference between remove and discard. Then we look at the set operations: union, intersection, difference, and the subset and superset checks, with all the directions shown. We end with removing duplicates, frozen sets, common mistakes and the full program. Every output comes from a real run on Python 3.13.

What are Python Sets?

A set is an unordered collection of unique items written in curly brackets.

  • Unique. A value can appear only once. Adding a duplicate does nothing.
  • Unordered. Items have no position. You cannot ask for the first one.
  • Mutable. You can add and remove items. A set can change, but the items inside it must be unchangeable.
  • Fast to search. Checking whether a value is in a set is much quicker than searching a list.

Creating a Set

python
x = {1, 2, 4, 45}
print(x)
print({3, 1, 3, 2, 1})
print(set([5, 5, 6, 7]))
print(sorted(set("hello")))
output
{1, 2, 4, 45}
{1, 2, 3}
{5, 6, 7}
['e', 'h', 'l', 'o']
  • The second line had five numbers, but the set holds only three, because the repeats were dropped.
  • set() turns another collection, such as a list, into a set.
  • A string passed to set splits into single characters, and the repeated l in hello appears once. We used sorted here because the order of text items in a set can change from run to run.

The Empty Set Trap

Empty curly brackets make a dictionary, not a set. To get an empty set, use set().

python
empty_wrong = {}
empty_right = set()
print(type(empty_wrong), type(empty_right))
output
<class 'dict'> <class 'set'>

No Order, No Indexing

Since a set has no order, you cannot get an item by position. Small whole numbers often print in sorted order, but never rely on that.

python
x = {1, 2, 4, 45}
try:
    x[0]
except TypeError as error:
    print("TypeError:", error)
output
TypeError: 'set' object is not subscriptable

Looping and Checking Membership

A for loop visits every item. The in word checks whether a value is present.

python
x = {1, 2, 3, 4, 5, 6}
for z in x:
    print(z, end=" ")
print()
print(1 in x, 9 in x, 9 not in x)
output
1 2 3 4 5 6 
True False True

Methods for Sets in Python

Set methods at a glance
Method What it does Returns
add(item) Adds one item None
update(iterable) Adds many items at once None
remove(item) Removes an item, error if missing None
discard(item) Removes an item, no error if missing None
pop() Removes and returns an arbitrary item The item
clear() Removes every item None
copy() Makes a copy A new set
union(other) All items from both A new set
intersection(other) Items found in both A new set
difference(other) Items in the first but not the second A new set
symmetric_difference(other) Items in one but not both A new set
issubset(other) Is every item also in the other set? True or False
issuperset(other) Does it contain every item of the other? True or False
isdisjoint(other) Do the two share nothing? True or False

add()

add puts in one item. Adding something that is already there changes nothing.

python
x = {1, 2, 3, 4, 5, 6}
x.add(9)
print(x)
x.add(9)
print(len(x))
output
{1, 2, 3, 4, 5, 6, 9}
7

update()

update adds many items from an iterable, such as a list, a tuple, or another set. Put the numbers in a list. Separate numbers, as in x.update(8, 11), fail.

python
x = {1, 2, 3, 4, 5, 6, 9}
x.update([8, 11, 44, 22])
print(x)
x.update([100], {200, 300})
print(sorted(x))
try:
    x.update(8, 11)
except TypeError as error:
    print("TypeError:", error)
output
{1, 2, 3, 4, 5, 6, 8, 9, 11, 22, 44}
[1, 2, 3, 4, 5, 6, 8, 9, 11, 22, 44, 100, 200, 300]
TypeError: 'int' object is not iterable

You can pass more than one iterable, as the second line shows.

len()

len counts the items. It is a built in function, not a set method.

python
print(len({1, 2, 3}))
output
3

remove() and discard()

Both take out an item. The difference is what happens when the item is missing. remove raises a KeyError, and discard stays silent.

python
x = {1, 2, 3, 4, 5, 6}
x.remove(2)
print(x)
x.discard(99)
try:
    x.remove(99)
except KeyError as error:
    print("KeyError:", error)
output
{1, 3, 4, 5, 6}
KeyError: 99

The discard call on 99 did nothing and raised no error. The remove call on 99 raised the KeyError.

pop()

pop removes one item and hands it back. A set has no order, so it does not remove from the end. It removes an arbitrary item, and you cannot choose which one.

python
x = {1, 3, 4, 5, 6}
popped = x.pop()
print(popped in {1, 3, 4, 5, 6}, len(x))
output
True 4

clear()

python
x = {1, 3, 4, 5}
x.clear()
print(x, len(x))
output
set() 0

An empty set prints as set(), not as {}, to avoid mixing it up with an empty dictionary.

del

There is no x.delete() method. del is a statement, not a method. It removes the name itself, so using the set afterwards fails.

python
gone = {1, 2}
del gone
try:
    print(gone)
except NameError as error:
    print("NameError:", error)
output
NameError: name 'gone' is not defined

copy()

python
a = {1, 2, 3}
b = a.copy()
b.add(4)
print(a, b)
output
{1, 2, 3} {1, 2, 3, 4}

The copy is independent, so adding to b did not touch a.

Set Operations

Take two sets, x and y. Each operation has a method and a shortcut operator.

python
x = {1, 2, 3, 4, 5, 6}
y = {4, 5, 6, 7, 8}
print(x.union(y), x | y)
print(x.intersection(y), x & y)
print(x.difference(y), x - y)
print(x.symmetric_difference(y), x ^ y)
output
{1, 2, 3, 4, 5, 6, 7, 8} {1, 2, 3, 4, 5, 6, 7, 8}
{4, 5, 6} {4, 5, 6}
{1, 2, 3} {1, 2, 3}
{1, 2, 3, 7, 8} {1, 2, 3, 7, 8}
Set operators
Operation Operator In plain words
union | Everything in either set
intersection & Only what both sets have
difference – In the first set but not in the second
symmetric difference ^ In one set but not in both

Think of the maths club and the science club. The union is everyone in either club. The intersection is the students who joined both. The difference is the students in maths who are not in science.

issubset() and issuperset()

A set is a subset of another if every one of its items is also in the other. The other set is then a superset of it. The direction matters. Here x has 6 items and small has 3 of them:

python
x = {1, 2, 3, 4, 5, 6}
small = {4, 5, 6}
print(x.issubset(small))
print(small.issubset(x))
print(x.issuperset(small))
print(small.issuperset(x))
output
False
True
True
False
Subset and superset checks
Question Answer Why
Is x a subset of small? False x has items that small lacks
Is small a subset of x? True Every item of small is in x
Is x a superset of small? True x contains all of small
Is small a superset of x? False small is missing items of x

isdisjoint()

isdisjoint is True when two sets share no items.

python
print({1, 2}.isdisjoint({3, 4}), {1, 2}.isdisjoint({2, 3}))
output
True False

Items in a Set Must Be Unchangeable

A set can only hold hashable items, which in practice means items that cannot change. Numbers, text and tuples work. A list does not.

python
try:
    bad = {[1, 2], 3}
except TypeError as error:
    print("TypeError:", error)
print({(1, 2), 3} == {3, (1, 2)})
output
TypeError: unhashable type: 'list'
True

The last line shows a tuple inside a set, and that two sets with the same items are equal in any order.

Removing Duplicates With a Set

This is the most common real use of a set. Turn a list into a set and back.

python
names = ["Asha", "Ravi", "Asha", "Meena", "Ravi"]
print(sorted(set(names)))
print(list(dict.fromkeys(names)))
output
['Asha', 'Meena', 'Ravi']
['Asha', 'Ravi', 'Meena']

The first line removes the duplicates but loses the original order, so the output is sorted here. If order matters, use the second form. A dictionary remembers the order of first appearance, and it gave Asha, Ravi, Meena, the order they came in.

Set Comprehension and Frozen Sets

python
print({n % 3 for n in range(10)})
output
{0, 1, 2}

A set comprehension builds a set in one line. Ten numbers gave only three remainders, because the repeats collapsed.

A frozenset is a set that cannot be changed. Because it is unchangeable, it can be used as a dictionary key or placed inside another set.

python
fs = frozenset([1, 2, 3])
try:
    fs.add(4)
except AttributeError as error:
    print("AttributeError:", error)
output
AttributeError: 'frozenset' object has no attribute 'add'

Set Compared With List, Tuple and Dictionary

Four collection types compared
Type Written as Ordered Duplicates Best for
List [1, 2, 3] Yes Allowed A collection that grows or changes
Tuple (1, 2, 3) Yes Allowed A fixed group of values
Set {1, 2, 3} No Not allowed Unique items and group comparisons
Dictionary {“a”: 1} Yes Keys must be unique Looking up values by key

Common Mistakes to Avoid

  • Using empty curly brackets for an empty set. That makes a dictionary. Use set().
  • Expecting order. A set has no order and no index.
  • Passing separate numbers to update. Pass one iterable, such as a list.
  • Using remove for an item that may be missing. It raises a KeyError. Use discard.
  • Getting the direction of subset and superset wrong. A.issubset(B) asks whether A fits inside B.
  • Putting a list inside a set. Lists cannot be hashed. Use a tuple.
  • Using a set to remove duplicates when order matters. Use dict.fromkeys instead.
  • Writing set.delete(). It does not exist. Use del, or clear to empty it.

Try It Yourself: The Full Program

The program below holds every example in this tutorial. Copy it into a file, run it, and compare your output with what you see above.

python
import sys
print("Python", sys.version_info.major, sys.version_info.minor)

# Creating sets
x = {1, 2, 4, 45}
print(x)
print({3, 1, 3, 2, 1})
print(set([5, 5, 6, 7]))
print(sorted(set("hello")))
empty_wrong = {}
empty_right = set()
print(type(empty_wrong), type(empty_right))

# No order and no indexing
try:
    x[0]
except TypeError as error:
    print("TypeError:", error)

# Looping and membership
x = {1, 2, 3, 4, 5, 6}
for z in x:
    print(z, end=" ")
print()
print(1 in x, 9 in x, 9 not in x)

# Adding
x.add(9)
print(x)
x.add(9)
print(len(x))
x.update([8, 11, 44, 22])
print(x)
x.update([100], {200, 300})
print(sorted(x))
try:
    x.update(8, 11)
except TypeError as error:
    print("TypeError:", error)

# Removing
x = {1, 2, 3, 4, 5, 6}
x.remove(2)
print(x)
x.discard(99)
try:
    x.remove(99)
except KeyError as error:
    print("KeyError:", error)
popped = x.pop()
print(popped in {1, 3, 4, 5, 6}, len(x))
x.clear()
print(x, len(x))
gone = {1, 2}
del gone
try:
    print(gone)
except NameError as error:
    print("NameError:", error)

# Copy
a = {1, 2, 3}
b = a.copy()
b.add(4)
print(a, b)

# Set operations
x = {1, 2, 3, 4, 5, 6}
y = {4, 5, 6, 7, 8}
print(x.union(y), x | y)
print(x.intersection(y), x & y)
print(x.difference(y), x - y)
print(x.symmetric_difference(y), x ^ y)

# Subset and superset
small = {4, 5, 6}
print(x.issubset(small))
print(small.issubset(x))
print(x.issuperset(small))
print(small.issuperset(x))
print({1, 2}.isdisjoint({3, 4}), {1, 2}.isdisjoint({2, 3}))

# Items must be unchangeable
try:
    bad = {[1, 2], 3}
except TypeError as error:
    print("TypeError:", error)
print({(1, 2), 3} == {3, (1, 2)})

# Removing duplicates, and what it costs
names = ["Asha", "Ravi", "Asha", "Meena", "Ravi"]
print(sorted(set(names)))
print(list(dict.fromkeys(names)))

# Set comprehension and frozenset
print({n % 3 for n in range(10)})
fs = frozenset([1, 2, 3])
try:
    fs.add(4)
except AttributeError as error:
    print("AttributeError:", error)

 

Sets do one job very well: they keep things unique and make group comparisons easy. Run the examples, change the numbers, and watch how union, intersection and difference behave. When they feel natural, you will reach for a set whenever you hear the words unique, duplicate or overlap. Then move on to the other Python data types to see how all five fit together.

Popular Tags:

Sets in Python Tutorial