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 or pop() an empty set will result in a KeyError. discard() won’t result in a KeyError.

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 AB, 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 AB, 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']
See forum comments
Download course materials from Github
Previous: Introduction Next: Comprehensions