Sets
A set is an unordered collection of unique values. Sets automatically ignore duplicates, and they're great for questions like "Which students are in both classes?" or "Have we seen this value before?"
Creating a set
Write the values inside curly braces, or convert another collection with set():
colors = {"red", "green", "blue", "red", "green"}
print(colors) # duplicates are gone
print(len(colors))
numbers = set([1, 2, 2, 3, 3, 3])
print(numbers)Sets have no order, so the items may print in any order, and you can't use indexes like colors[0].
Watch out:
{}creates an empty dictionary, not a set. Useset()for an empty set.
print(type({}))
print(type(set()))Removing duplicates
The most common use of a set is removing duplicates from a list:
visitors = ["ana", "ben", "ana", "cleo", "ben", "ana"] unique = set(visitors) print(unique) print(len(unique), "unique visitors") print(sorted(unique)) # back to an ordered list
Adding and removing
tags = {"python", "code"}
tags.add("beginner")
tags.add("python") # already there, nothing happens
print(tags)
tags.remove("code") # KeyError if missing
tags.discard("java") # no error if missing
print(tags)Fast membership tests
in works on lists too, but sets are built for it. Checking a set stays fast no matter how big the set gets:
banned_words = {"spam", "scam", "free money"}
print("spam" in banned_words)
print("hello" in banned_words)Set operations
Sets are great for comparing two groups. Imagine two school clubs:
chess = {"Ana", "Ben", "Cleo", "Dev"}
drama = {"Cleo", "Dev", "Eli", "Fay"}
print(chess | drama) # in either club (or both)
print(chess & drama) # in both clubs
print(chess - drama) # in chess but not drama
print(drama - chess) # in drama but not chess| Question | Operator | Name |
|---|---|---|
| Who is in either club? | a | b |
union |
| Who is in both clubs? | a & b |
intersection |
Who is in a but not b? |
a - b |
difference |
Going deeper: More ways to compare sets optional
^ gives the items that are in exactly one of the sets (the "symmetric difference"):
chess = {"Ana", "Ben", "Cleo", "Dev"}
drama = {"Cleo", "Dev", "Eli", "Fay"}
print(chess ^ drama)Each operator also has a method version, such as chess.union(drama) or chess.intersection(drama).
Subset checks tell you whether one set is completely inside another:
required = {"python", "git"}
skills = {"python", "git", "sql", "docker"}
print(required.issubset(skills)) # are all required skills present?
print(required <= skills) # same thing
print(skills.issuperset(required))
print(required.isdisjoint({"java"})) # nothing in common?Going deeper: What can go in a set? optional
Like dictionary keys, set items must be immutable: numbers, strings and tuples are fine, but lists aren't:
points = {(0, 0), (1, 2), (0, 0)}
print(points)
bad = {[1, 2], [3, 4]}Going deeper: Frozen sets optional
A frozenset is a set that can't be changed, just as a tuple is a list that can't be changed. You can still test membership and compare it with other sets, but add and remove don't exist:
vowels = frozenset("aeiou")
print("e" in vowels)
print(len(vowels))
vowels.add("y")Because it can't change, a frozenset can go inside another set or be a dictionary key. That's handy for pairs where the order doesn't matter:
matches = {frozenset({"Ana", "Ben"}), frozenset({"Ben", "Ana"})}
print(len(matches)) # the same pair, so it's stored onceExercises
Exercise 1: Unique words
Print how many different words are in the sentence. It should print 7. Hint: split the sentence, then make a set.
sentence = "the cat and the dog and the bird saw a cat"
sentence.split() gives a list of words.
Turn the list into a set to remove repeats, then use len().
Exercise 2: Common friends
Print the friends that Ana and Ben have in common, as a sorted list: ['Cleo', 'Eli'].
ana_friends = {"Cleo", "Dev", "Eli", "Gus"}
ben_friends = {"Eli", "Fay", "Cleo", "Hal"}
The & operator keeps only the items that are in both sets.
Wrap the result in sorted() to get an ordered list.
Exercise 3: Missing items
needed is what a recipe requires and have is what's in the kitchen. Print a sorted list of what you still need to buy: ['eggs', 'sugar'].
needed = {"flour", "eggs", "sugar", "butter"}
have = {"flour", "butter", "milk"}
The - operator keeps what is in the first set but not in the second.
Wrap the result in sorted().
Exercise 4: Any duplicates?
Print True if the list contains any duplicate values, otherwise False. Compare the length of the list with the length of a set made from it.
ids = [104, 221, 309, 104, 412]
A set removes duplicates. If the set is smaller than the list, something was repeated.
Compare len(ids) with len(set(ids)).
Set methods at a glance
Each example starts from s = {1, 2, 3}. The Result column shows what the method gives back, or what s looks like afterwards for methods that change it.
| Method | What it does | Example | Result |
|---|---|---|---|
add(x) |
Adds x (nothing happens if it's already there) |
s.add(4) |
{1, 2, 3, 4} |
update(items) |
Adds every item from another collection | s.update([4, 5]) |
{1, 2, 3, 4, 5} |
remove(x) |
Removes x (KeyError if missing) |
s.remove(2) |
{1, 3} |
discard(x) |
Removes x if it's there, no error if not |
s.discard(9) |
{1, 2, 3} |
pop() |
Removes and returns an arbitrary item | s.pop() |
returns one item, e.g. 1 |
clear() |
Removes every item | s.clear() |
set() |
copy() |
Returns a new copy | s.copy() |
{1, 2, 3} |
union(other) or s | other |
Items in either set | s | {3, 4} |
{1, 2, 3, 4} |
intersection(other) or s & other |
Items in both sets | s & {2, 3, 4} |
{2, 3} |
difference(other) or s - other |
Items in s but not in other |
s - {3, 4} |
{1, 2} |
symmetric_difference(other) or s ^ other |
Items in exactly one of the sets | s ^ {3, 4} |
{1, 2, 4} |
issubset(other) or s <= other |
Is every item of s also in other? |
{1, 2} <= s |
True |
issuperset(other) or s >= other |
Does s contain every item of other? |
s >= {1, 5} |
False |
isdisjoint(other) |
Do the sets have nothing in common? | s.isdisjoint({7, 8}) |
True |
len(s), x in s, sorted(s) and set(items) also work, just as they do for lists.
Summary
- A set holds unique values with no order:
{1, 2, 3}. set(some_list)removes duplicates. Useset(), not{}, for an empty set.add,removeanddiscardchange a set.inchecks membership quickly.|gives items in either set,&items in both, and-items in the first but not the second.