Sets
A sticker album has one spot for each sticker. Get a duplicate, and there's nowhere to put it. You either have that sticker or you don't.
A dictionary makes sure each key appears only once. Sometimes that's exactly what you need, without any values attached: which students signed up, which words appear in a story, which countries you've visited. You don't care how many times each one shows up, or in what order. You only care whether it's there.
For that, Python has the set.
A sticker album
A sticker album has exactly one place for each sticker. When you get a new one, you stick it in. When you get one you already have, it doesn't go in twice; it's just a duplicate. At any moment, the question the album answers is simple: do I have this sticker, yes or no?
A Python set works the same way:
- Every item in a set is unique. Adding something that's already there does nothing.
- A set has no order. There's no first item, and no index.
- Its best trick is answering "is this in here?" very quickly.
Making a set
Write the items between curly braces, like a dictionary without the colons:
signups = {"Maria", "Ben", "Carlo"}
numbers = {3, 1, 2, 3, 1}
print(len(signups))
print(numbers)3
{1, 2, 3}The duplicates in numbers simply vanished: a set only keeps one of each.
An empty set has to be written set(). Empty curly braces, {}, make an empty dictionary, since dictionaries came first:
empty = set()
not_a_set = {}
print(type(empty), type(not_a_set))<class 'set'> <class 'dict'>No order, so no indexes
Because a set has no order, you can't ask for "item 0":
signups = {"Maria", "Ben", "Carlo"}
print(signups[0]) # error: TypeError: 'set' object is not subscriptableThere's a subtler consequence, too. When you print a set of strings, the order can be different every time you run your program. Python chooses the order internally, and for strings, that choice changes from run to run on purpose, for security reasons. That's why the examples in this lesson wrap sets of strings in sorted() before printing them: sorted() gives back a list in alphabetical order, so the output is always the same.
Adding and removing
signups = {"Maria", "Ben"}
signups.add("Carlo")
signups.add("Maria")
print(sorted(signups))
signups.remove("Ben")
signups.discard("Eli")
print(sorted(signups))['Ben', 'Carlo', 'Maria']
['Carlo', 'Maria']addputs an item in. Adding"Maria"a second time changed nothing.removetakes an item out, and raises aKeyErrorif it isn't there.discardalso takes an item out, but quietly does nothing if it isn't there. Use it when you're not sure.
Is it in there? Fast.
Checking membership with in works for lists too, but for sets, it's dramatically faster. A list has to be searched from the start, item by item. A set jumps straight to the answer, the way a dictionary finds a key. For a few dozen items, you won't notice. For a million, a set answers instantly while a list takes a noticeable moment, every single time.
banned_words = {"spam", "scam", "free money"}
message = "Click here for free money"
for word in banned_words:
if word in message.lower():
print("Blocked:", word)Blocked: free moneyRemoving duplicates from a list
The most common everyday use of a set is removing duplicates. Turn a list into a set and back:
visits = ["Manila", "Cebu", "Manila", "Davao", "Cebu", "Manila"]
unique_places = sorted(set(visits))
print(unique_places)
print(len(unique_places), "different places")['Cebu', 'Davao', 'Manila']
3 different placesset(visits) keeps one of each, and sorted() turns the result back into a list in a predictable order.
Comparing groups: set math
Sets can be combined, like the Venn diagrams from math class. Say two clubs have these members:
chess = {"Ana", "Ben", "Carlo", "Dina"}
robotics = {"Carlo", "Dina", "Eli"}
print(sorted(chess | robotics))
print(sorted(chess & robotics))
print(sorted(chess - robotics))
print(sorted(chess ^ robotics))['Ana', 'Ben', 'Carlo', 'Dina', 'Eli']
['Carlo', 'Dina']
['Ana', 'Ben']
['Ana', 'Ben', 'Eli']| Operator | Name | Means |
|---|---|---|
a | b | union | in either club (or both) |
a & b | intersection | in both clubs |
a - b | difference | in the first club, but not the second |
a ^ b | symmetric difference | in exactly one club, not both |
Each operation gives back a new set and leaves the originals alone. There are method versions too, like chess.union(robotics), if you find names easier to read than symbols.
Lists, tuples, dictionaries, or sets?
You now know Python's four main collections. Here's how to choose:
| Use a... | When you need... |
|---|---|
| list | items in order, that may change, where duplicates are fine |
| tuple | a small fixed group of values that belong together |
| dictionary | to look values up by a key |
| set | unique items, fast "is it in here?" checks, or group comparisons |
Try it
A teacher is comparing who submitted two assignments. This program finds who did both, who did only one, and who's missing everything. Predict every line.
Running Python here
Running Python right in the browser is coming to Syntaxia soon. For now, you can read and edit the code here. If you have Python installed on your computer (see Setting Up), save it as main.py and run it with python main.py (or python3 main.py on macOS and Linux).
Check your prediction
Essay submissions (with repeats): 5
Different students who sent the essay: 4
Did both: ['Carlo', 'Eli']
Essay only: ['Ana', 'Dina']
Did at least one: 5
Missing both: ['Fe']
Is Fe in the quiz set? FalseAna submitted her essay twice, but the set only counts her once. Carlo and Eli are in both sets. Subtracting both sets from the roster leaves only the students who appear in neither.
Try it yourself
- Find the students who did the quiz but not the essay.
- Remove the
sorted()from one of the lines and run the program a few times. Does the order change between runs? - Given the sentence
"the cat saw the other cat", print how many different words it contains, usingsplit()and a set.
Check your understanding
Up next
Many of the loops in the last few lessons followed the same pattern: start with an empty list, loop, and append. Python has a compact way to write exactly that in one line: List and Dictionary Comprehensions.
