What a set is
A list keeps every value you put in it, repeats included. Sometimes you only care which values are there, not how often. A set holds each value once. Adding a value that is already in the set changes nothing.
The basic operations
set()makes an empty set.s.add(x)putsxin the sets.x in sisTruewhenxis in the set.len(s)gives how many values the set holds.set(lst)builds a set from a list. Its repeats go in once.
colors = set()
colors.add("red")
colors.add("blue")
colors.add("red")
print(len(colors))
print("blue" in colors)
print("pink" in colors)
pets = set(["cat", "dog", "cat"])
print(len(pets))
2
True
False
2
Checking x in s is fast, even for a big set: Python does not look at the values one by one. On a list, in does exactly that, so the work grows with the length of the list.
Traps
- No order, no indexes. A set has no first element.
kids[0]stops withTypeError: 'set' object is not subscriptable. A printed set may show its values in any order. {}is not an empty set. It makes an empty dictionary:type({})isdict. Writeset()for an empty set.- Equal sets ignore order.
set([1, 2, 3]) == set([3, 2, 1])isTrue.
What can go in a set
A set's values must be hashable, which is why the common cases work: numbers, strings and tuples can be set members, while lists cannot. s.add([1]) stops with TypeError: unhashable type: 'list'. Counting different values is the classic use: len(set("banana")) is 3, because the string has only the letters b, a and n, and sorted(set(["b", "a", "b"])) gives ['a', 'b'] when you do need an order.
When to choose a set over a list
Reach for a set when the questions are "is this value present?" and "how many different values are there?". Reach for a list when position or repeats matter: the third name on the sign-up sheet, or how many times a name was written down. A common pattern is to read data into a list, then build a set from it to answer the first kind of question quickly.
The exercise, step by step
A camp's sign-up list names has some names twice. The task is to build a set kids from it, add Zoe and then Ava, and print Leo is coming if Leo is in the set. The starter code already prints the number of kids twice.
- Build the set with
kids = set(names). Ava and Leo are in the list twice but go in the set once, so it holds Ava, Leo and Mia: 3 names. - Call
kids.add("Zoe")andkids.add("Ava"). Zoe is new, so the set grows to 4. Ava is already there, so that call changes nothing. - At the end, test
"Leo" in kidsand print the message when it is true.
names = ["Ava", "Leo", "Ava", "Mia", "Leo"]
kids = set(names)
print(len(kids), "kids")
kids.add("Zoe")
kids.add("Ava")
print(len(kids), "kids")
if "Leo" in kids:
print("Leo is coming")
3 kids
4 kids
Leo is coming
Key takeaways
- A set stores each value once;
addon an existing value does nothing. - Use
inon a set for a fast membership check. - Sets have no order and no indexes.
- Make an empty set with
set(), never with{}. set(list)is the quickest way to drop repeats and count the different values.
