Know some Python? Write your own interactive tutorial, with runnable examples and exercises, and share it with a link. Write and share your own tutorial.

Start writing

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)   # no duplicates
print(len(colors))

numbers = set([1, 2, 2, 3, 3, 3])
print(numbers)
Output

Sets have no order. The items may print in a different order from the one you typed, and the order can even change between runs. For the same reason you can't use indexes like colors[0]; that's a TypeError. Use sorted() when you need a predictable order.

set() works on any collection. Given a string, it gives you the unique characters: set("hello") is {'h', 'e', 'l', 'o'}, in some order.

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

# back to an ordered list
print(sorted(unique))
Output

The set keeps one copy of each name and throws the repeats away, so len() counts unique visitors. Two things are lost on the way: how many times each name appeared, and the original order. sorted() gives you back a list in alphabetical order. (To count repeats, use a dictionary, as in the Dictionaries lesson.)

Adding and removing

tags = {"python", "code"}

tags.add("beginner")

# already there, so nothing happens
tags.add("python")
print(tags)

tags.remove("code")

# not there, but no error
tags.discard("java")
print(tags)
Output
Method What it does If the item is already there / missing
add(x) adds one item already there: nothing happens
remove(x) removes the item missing: KeyError
discard(x) removes the item missing: nothing happens, no error

Use remove() when the item should definitely be there (so a mistake shows up as an error), and discard() when you just want to make sure it's gone.

Fast membership tests

in works on lists too, but sets are built for it. To answer in for a list, Python checks the items one by one, so a list of a million items can take a million checks. A set jumps straight to where the item would be, so the check 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"}

# in either club (or both)
print(chess | drama)

# in both clubs
print(chess & drama)

# in chess but not drama
print(chess - drama)

# in drama but not chess
print(drama - chess)
Output

Cleo and Dev are in both clubs, so they appear once in chess | drama (six names in all) and are the whole answer for chess & drama. Order matters for -: chess - drama is Ana and Ben, but drama - chess is Eli and Fay. Each operation gives a new set; chess and drama don't change.

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

# are all required skills present?
print(required.issubset(skills))
print(required <= skills)
print(skills.issuperset(required))

# nothing in common?
print(required.isdisjoint({"java"}))
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"})}
# the same pair: stored once
print(len(matches))
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.

Share this tutorial

Know something worth teaching? Write your own tutorial with runnable examples and share it.