Learn Python / Sets

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)
Output

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. Use set() for an empty set.

print(type({}))
print(type(set()))
Output

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
Output

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)
Output

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)
Output

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
Output
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)
Output

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?
Output
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]}
Output
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")
Output

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 once
Output

Exercises

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"
Output

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"}
Output

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"}
Output

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]
Output

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. Use set(), not {}, for an empty set.
  • add, remove and discard change a set. in checks membership quickly.
  • | gives items in either set, & items in both, and - items in the first but not the second.