7 min read
Sets and set operations
A collection with no duplicates
A set is a collection of items with two defining rules: every item is unique, and the items are unordered. There is no first or last, and no position to index by. What a set is very good at is answering "is this thing in here?" quickly, and keeping out repeats without you lifting a finger.
You write a set with curly braces, like a dictionary but with plain values and no colons:
colours = {"red", "green", "blue"}
Add a duplicate and the set simply ignores it, because it already has that value:
colours.add("red")
print(colours) # still {"red", "green", "blue"}, in some order
Because there is no order, the arrangement you see when you print a set is arbitrary and is not something to rely on. It may differ between runs, and it may not: with text it usually varies, with small whole numbers it often looks stable. Neither is a promise. If order matters to you, a set is the wrong tool; if uniqueness matters, it is exactly the right one.
Building and testing a set
You add one item with .add() and several at once with .update(). You test membership with in, and you take an item out with .remove():
sizes = {36, 38, 40}
sizes.add(42)
sizes.update([44, 46])
print(38 in sizes) # True
sizes.remove(36)
The membership test 38 in sizes is the headline feature. On a long list, checking in means scanning item by item; on a set it is typically near instant, and stays that way as the set grows. When your program keeps asking "have I seen this before?", a set is usually the answer.
The quickest way to strip duplicates from a list is to pour it into a set and, if you still want a list, pour it back:
ids = [4, 2, 4, 7, 2, 9, 7]
unique_ids = list(set(ids)) # duplicates gone
Comparing two sets
Sets earn their keep when you compare two of them. Three operations cover most needs, and each answers a plain-language question about two groups:
- Union (
|) gathers everything in either set: all the items across both, still with no repeats. - Intersection (
&) keeps only what is in both: the overlap. - Difference (
-) keeps what is in the first but not the second.
morning = {"Ana", "Ben", "Cara"}
evening = {"Ben", "Dea", "Cara"}
print(morning | evening) # everyone who came to either class
print(morning & evening) # who came to both
print(morning - evening) # who came only in the morning
Written as loops, each of these would take several lines and an if. As set operations they are a single symbol that reads almost like the question you started with.
A worked example: common interests
Say two students each list the clubs they belong to, and you want to suggest an activity they could do together. That is an intersection: the clubs that appear on both lists.
def shared_clubs(first, second):
return set(first) & set(second)
ana = ["chess", "hiking", "choir", "coding"]
ben = ["coding", "football", "chess", "art"]
print(shared_clubs(ana, ben)) # {"chess", "coding"}
Wrapping each list in set(...) does double duty: it removes any accidental repeats and unlocks the & operator. The result is the two clubs they have in common, found in one clean line instead of a nested loop that compares every club against every other.
Tip
Ask yourself what the collection is really for. If you need order or you allow duplicates, use a list. If you need fast "is it in here?" checks or you want duplicates gone, use a set. Matching the tool to the job is half of writing clear code.
Try this now
Take two short lists of names, wrap each in set(...), and print three things: everyone in either list with |, the names in both with &, and the names in the first only with -. Check that each result matches what you would work out by hand.
Check yourself
- A set is unordered and holds each item only once. Name one task where those two properties are a perfect fit, and one task where they make a set the wrong choice.
- Why is testing
x in my_settypically much faster than testingx in my_listwhen the collection is large? - Two sets
aandbdescribe who signed up for two trips. Which set operation gives you the people who signed up for both, and which gives you those who signed up for the first trip only?
Where this lesson comes from
Built from
- Data Structures and Algorithms
- Further reading: Brian Heinold, A Practical Introduction to Python Programming
alphaPlan courses are built from taught programmes rather than invented for the web. Where a claim rests on an outside standard or a reported case, it is named above so you can check it rather than take our word for it.
This course was developed by alphaPlan Center from programs delivered in partnership with the American Corners network.
Found something unclear, outdated or improvable? Suggest an improvement