Sets
Sets
Many programmers new to Python, and even some experienced ones, often underutilize the features covered in this section. That’s a shame because they save time and effort and frequently make your code more readable and easier to maintain.
Python’s most underused collection type is the set, an unordered collection of unique objects. If you wanted to describe sets in terms of other Python collection types, you could say they’re like lists that ignore order and don’t allow duplicate items.
Like dictionaries, set literals use braces, often called curly brackets, as delimiters. However, unlike dictionaries, they contain individual items rather than key-value pairs.
Here’s an example of creating a non-empty set:
my_genres = {"documentary", "comedy", "science fiction", "drama"}
Sets are handy for building collections of unique items and performing set operations, which are useful for categorizing items or figuring out where to put things in a Venn diagram.
But before performing set operations, you must know how to create sets and add and remove items to and from them.
Create, Add, and Remove Set Items
The only way to create an empty set is to use object initialization syntax:
empty_set = set()
You can’t create an empty set using a set literal because {} already represents an empty dictionary.
As with just about every Python type, you can confirm the set’s type with the type() function:
type(empty_set) # set
Use the add() method to add a single item to a set:
# Let’s start with an empty set of show genres
alice = set()
# Now let’s add a genre
alice.add("comedy")
alice # {'comedy'}
To add multiple items to a set, use the update() method, which takes a list of items:
# Add more genres to Alice’s set
more_genres = ["musical", "romance", "anime", "comedy"]
alice.update(more_genres)
alice # {'anime', 'comedy', 'musical', 'romance'}
There are several ways to remove an item from a set. Sets have the discard() method, along with the remove() and pop() methods, which are analogous to their counterparts in lists:
alice = {
"anime",
"comedy",
"musical",
"romance"
}
# discard() removes a specific item from a set:
alice # {'anime', 'comedy', 'musical', 'romance'}
alice.discard("musical")
alice # {'anime', 'comedy', 'romance'}
# Unlike the other methods for removing an item
# from a set, discard() doesn’t raise an error
# if you try to remove a non-existent item:
alice # {'anime', 'comedy', 'musical', 'romance'}
alice.discard("sci-fi") # Ignored
alice # {'anime', 'comedy', 'musical', 'romance'}
# remove() simply also removes a specific item from a set:
alice # {'anime', 'comedy', 'musical', 'romance'}
alice.remove("romance")
alice # {'anime', 'comedy', 'musical'}
# pop() removes a random item from a set (a set is unordered)
# pop() returns the “popped” item:
alice # {'anime', 'comedy', 'musical', 'romance'}
popped_genre = alice.pop()
popped_genre # The popped item is random
alice # alice may look like this: {'anime', 'musical', 'romance'}
Note: Attempting to
remove()an item that isn’t in a set results orpop()an empty set will result in aKeyError.discard()won’t result in aKeyError.
Elements in a Set
To test if a given item is in a set, use the in operator:
found = "sci-fi" in my_genres # True if `my_genres` contains "sci-fi"
An index or key can’t access elements in a set, but you can use a for loop:
my_genres # {'anime', 'comedy', 'musical', 'romance'}
for genre in my_genres:
print(genre)
# comedy
# musical
# anime
# romance
Set Operations
Sets were included in Python to perform set operations, which can be performed more quickly in sets than in other collections.
For the example code for set operations, assume the following sets have been created:
alice = {"anime", "comedy", "musical", "romance"}
bob = {"documentary"}
carol = {"anime", "sci-fi", "fantasy"}
dinesh = {"anime", "comedy", "musical"}
eiko = {"anime", "sci-fi", "fantasy"}
Union
The union of two sets, A and B, mathematically written as A ∪ B, combines the elements of A and B, with any duplicates removed.
# Both lines below create the union of
# Alice and Bob’s genres
genres = alice.union(bob)
genres = alice | bob
The union of alice and bob is:
{'anime', 'comedy', 'documentary', 'musical', 'romance'}
Intersection
The intersection of two sets, A and B, mathematically written as A ∩ B, is the set of elements that are both in A and B.
# Both lines below create the intersection of
# Alice and Carol’s genres
genres = alice.intersection(carol)
genres = alice & carol
The intersection of alice and carol is:
{'anime'}
Using Sets to Remove Duplicates From a List
One of the most common uses for sets is removing duplicates from a list. You can do this by converting a list into a set and then converting the resulting set back into a list:
list_with_duplicate_genres = ["comedy", "comedy", "drama", "fantasy",
"fantasy", "musical", "sci-fi", "sci-fi"]
list_with_unique_genres = list(set(list_with_duplicate_genres))
After running the code above, list_with_duplicate_genres contains this list:
['sci-fi', 'musical', 'fantasy', 'drama', 'comedy']