Python Sets#

Learn everything about Python sets; how they are created, adding or removing elements from them, and all operations performed on sets in Python.

What is Set in Python?#

A set is an unordered collection of items. Every set element is unique (no duplicates) and must be immutable (cannot be changed).

However, a set itself is mutable. We can add or remove items from it.

Sets can also be used to perform mathematical set operations like union, intersection, symmetric difference, etc.

Summary#

Data types

Type

String

immutable

List

mutable

Tuple

immutable

Dictionary

mutable

Set

immutable

How Are Sets Better Than Other DataTypes?#

Sets will not contain multiple occurrences of the same element, they are very useful in removing duplicate elements from a list or a tuple. Also, they are useful in computing mathematical notations such as union, intersection, etc.

Creating Python Sets#

A set is created by placing all the items (elements) inside curly braces {}, separated by comma, or by using the built-in set() function.

It can have any number of items and they may be of different types (integer, float, tuple, string etc.). But a set cannot have mutable elements like lists, sets or dictionaries as its elements.

# Example 1: Different types of sets in Python

# set of integers
my_set = {5, 7, 1, 2, 3}            
print(my_set)           # ā–¶ {1, 2, 3, 5, 7}
 
# set of mixed datatypes
my_set = {1.0, "Hello", (1, 2, 3)}  
print(my_set)           # ā–¶ {1.0, 'Hello', (1, 2, 3)}
{1, 2, 3, 5, 7}
{1.0, (1, 2, 3), 'Hello'}
# Example 2: Different types of sets in Python

# set cannot have duplicates
my_set = {1, 2, 3, 4, 3, 2}
print(my_set)             # ā–¶ {1, 2, 3, 4}

# we can make set from a list
my_set = set([1, 2, 3, 2])
print(my_set)             # ā–¶ {1, 2, 3}

# set can have immutable items
# here (3, 4) is a immutable list

my_set = {1, 2, (3, 4)}   
print(my_set)            # ā–¶ {1, 2, (3, 4)} āˆµ tuple is immutable

# set cannot have mutable items
# here [3, 4] is a mutable list

my_set = {1, 2, [3, 4]}  # this will cause an error āˆµ list is mutable
{1, 2, 3, 4}
{1, 2, 3}
{1, 2, (3, 4)}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[1], line 20
     15 print(my_set)            # ā–¶ {1, 2, (3, 4)} āˆµ tuple is immutable
     17 # set cannot have mutable items
     18 # here [3, 4] is a mutable list
---> 20 my_set = {1, 2, [3, 4]}  # this will cause an error āˆµ list is mutable

TypeError: unhashable type: 'list'

Creating an empty set is a bit tricky.#

Empty curly braces {} will make an empty dictionary in Python. To make a set without any elements, we use the set() function without any argument.

# Example: Distinguish set and dictionary while creating empty set

# initialize a with {}
a = {}

# check data type of a
print(type(a))  # ā–¶ <class 'dict'> āˆµ dict also use {}

# initialize a with set()
a = set()

# check data type of a
print(type(a)) # ā–¶ <class 'set'>
<class 'dict'>
<class 'set'>

Modifying a set in Python#

Sets are mutable. However, since they are unordered, indexing has no meaning.

We cannot access or change an element of a set using indexing or slicing. Set data type does not support it.

We can add a single element using the add() method, and multiple elements using the update() method. The update() method can take tuples, lists, strings or other sets as its argument. In all cases, duplicates are avoided.

# Example: 

# initialize my_set
my_set = {1, 3}
print(my_set)      # ā–¶ {1, 3}

# my_set[0]
# if you uncomment above line, you will get an error
# TypeError: 'set' object does not support indexing

# add an element
my_set.add(2)
print(my_set)     # ā–¶ {1, 2, 3}

# add multiple elements
my_set.update([2, 3, 4])
print(my_set)     # ā–¶ {1, 2, 3, 4}

# add list and set
my_set.update([1,7],(8,9,10),{1,5,9,10})
print(my_set)     # ā–¶ {1, 2, 3, 4, 5, 7, 8, 9, 10}
{1, 3}
{1, 2, 3}
{1, 2, 3, 4}
{1, 2, 3, 4, 5, 7, 8, 9, 10}

Removing elements from a set#

A particular item can be removed from a set using the methods discard() and remove().

The only difference between the two is that the discard() function leaves a set unchanged if the element is not present in the set. On the other hand, the remove() function will raise an error in such a condition (if element is not present in the set).

The following example will illustrate this.

# Example: Difference between discard() and remove()

# initialize my_set
my_set = {1, 3, 4, 5, 6}
print(my_set)     # ā–¶ {1, 3, 4, 5, 6}

# discard an element
my_set.discard(4)
print(my_set)     # ā–¶ {1, 3, 5, 6}

# remove an element
my_set.remove(6)
print(my_set)     # ā–¶ {1, 3, 5}

# discard an element not present in my_set
my_set.discard(2)
print(my_set)     # ā–¶ {1, 3, 5} NO ERROR!

# remove an element not present in my_set you will get an error.
my_set.remove(2)  # ā–¶ KeyError!!!
{1, 3, 4, 5, 6}
{1, 3, 5, 6}
{1, 3, 5}
{1, 3, 5}
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-5-3bfaa309574d> in <module>
     18 
     19 # remove an element not present in my_set you will get an error.
---> 20 my_set.remove(2)  # Output: KeyError!!!

KeyError: 2

Similarly, we can remove and return an item using the pop() method.

Since set is an unordered data type, there is no way of determining which item will be popped. It is completely arbitrary.

We can also remove all the items from a set using the clear() method.

# Example:

# initialize my_set
my_set = set("HelloWorld")
print(my_set)        # ā–¶ unorderd set of unique elements

# pop an element
print(my_set.pop())  # ā–¶ removes a random element

# pop another element
my_set.pop()
print(my_set)

# clear my_set
my_set.clear()
print(my_set)        # ā–¶ set()
{'W', 'H', 'r', 'd', 'e', 'o', 'l'}
W
{'r', 'd', 'e', 'o', 'l'}
set()

Python Set Operations#

Sets can be used to carry out mathematical set operations like union, intersection, difference and symmetric difference. We can do this with operators or methods.

Let us consider the following two sets for the following operations.

>>> A = {1, 2, 3, 4, 5}
>>> B = {4, 5, 6, 7, 8}

Set Union#

Union of A and B is a set of all elements from both sets.

Union is performed using | operator. Same can be accomplished using the union() method.

# Example 1:

# Set union method
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# use | operator
print(A | B)      # ā–¶ {1, 2, 3, 4, 5, 6, 7, 8}
{1, 2, 3, 4, 5, 6, 7, 8}
# Example 2:

# use union function
A.union(B)
{1, 2, 3, 4, 5, 6, 7, 8}

# use union function on B
B.union(A)
{1, 2, 3, 4, 5, 6, 7, 8}
{1, 2, 3, 4, 5, 6, 7, 8}

Set Intersection#

Intersection of A and B is a set of elements that are common in both the sets.

Intersection is performed using & operator. Same can be accomplished using the intersection() method.

# Example 1:

# Intersection of sets
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# use & operator
print(A & B)     # ā–¶ {4, 5}
{4, 5}
# Example 2:

# use intersection function on A
A.intersection(B) # ā–¶ {4, 5}

# use intersection function on B
B.intersection(A) # ā–¶ {4, 5}
{4, 5}

Set Difference#

Difference of the set B from set A, (A - B) is a set of elements that are only in A but not in B. Similarly, B - A is a set of elements in B but not in A.

Difference is performed using - operator. Same can be accomplished using the difference() method.

# Example 1:

# Difference of two sets
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# use - operator on A
print(A - B)    # ā–¶ {1, 2, 3}
print(B - A)    # ā–¶ {8, 6, 7}
{1, 2, 3}
{8, 6, 7}
# Example 2:

# use difference function on A
A.difference(B) # ā–¶ {1, 2, 3}

# use difference function on B
B.difference(A) # ā–¶ {6, 7, 8}
{6, 7, 8}

Set Symmetric Difference#

Symmetric Difference of A and B is a set of elements in A and B but not in both (excluding the intersection).

Symmetric difference is performed using ^ operator. Same can be accomplished using the method symmetric_difference().

# Example 1:

# Symmetric difference of two sets
# initialize A and B
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# use ^ operator
print(A ^ B)    # ā–¶ {1, 2, 3, 6, 7, 8}
{1, 2, 3, 6, 7, 8}
# Example 2:

# use symmetric_difference function on A
A.symmetric_difference(B)  # ā–¶ {1, 2, 3, 6, 7, 8}

# use symmetric_difference function on B
B.symmetric_difference(A)  # ā–¶ {1, 2, 3, 6, 7, 8}
{1, 2, 3, 6, 7, 8}

Built-in Functions with Set#

Built-in functions like all(), any(), enumerate(), len(), max(), min(), sorted(), sum(), etc. are commonly used with sets to perform different tasks.

Function

Description

all()

Returns True if all elements of the set are true (or if the set is empty).

any()

Returns True if any element of the set is true. If the set is empty, returns False.

enumerate()

Returns an enumerate object. It contains the index and value for all the items of the set as a pair.

len()

Returns the length (the number of items) in the set.

max()

Returns the largest item in the set.

min()

Returns the smallest item in the set.

sorted()

Returns a new sorted list from elements in the set(does not sort the set itself).

sum()

Returns the sum of all elements in the set.

Other Python Set Methods#

There are many set methods, some of which we have already used above. Here is a list of all the methods that are available with the set objects:

Method

Operator

Description

add()

Adds an element to the set.

copy()

Returns a copy of the set.

remove()

Removes an element from the set. If the element is not a member, raises a KeyError.

discard()

Removes an element from the set if it is a member. (Do nothing if the element is not in set).

pop()

Removes and returns an arbitrary set element. Raises KeyError if the set is empty.

clear()

Removes all elements from the set.

union()

A | B

Returns the union of sets in a new set.

update()

A |= B

Updates the set with the union of itself and others.

intersection()

A & B

Returns the intersection of two sets as a new set.

intersection_update()

A &= B

Updates the set with the intersection of itself and another.

isdisjoint()

Returns True if two sets have a null intersection.

difference()

A ā€“ B

Returns the difference of two or more sets as a new set.

difference_update()

A -= B

Removes all elements of another set from this set.

symmetric_difference()

A ^ B

Returns the symmetric difference of two sets as a new set.

symmetric_difference_update()

A ^= B

Updates a set with the symmetric difference of itself and another.

issubset()

A <= B

Returns True if another set contains this set.

issuperset()

A >= B

Returns True if this set contains another set.

Other Set Operations#

1. Set Membership Test#

We can test if an item exists in a set or not, using the in keyword.

# Example:

# in keyword in a set
# initialize my_set
my_set = set("apple")

# check if 'a' is present
print('a' in my_set)      # ā–¶ True

# check if 'p' is present
print('p' not in my_set)  # ā–¶ False
True
False

2. Iterating Through a Set#

We can iterate through each item in a set using a for loop.

for letter in set("apple"):
    print(letter)  # ā–¶ āˆµ unorderd set of unique elements
p
a
e
l

Python Frozenset#

Frozenset is a new class that has the characteristics of a set, but its elements cannot be changed once assigned. While tuples are immutable lists, frozensets are immutable sets.

Sets being mutable are unhashable, so they canā€™t be used as dictionary keys. On the other hand, frozensets are hashable and can be used as keys to a dictionary.

Frozensets can be created using the frozenset() function.

The frozenset() function returns an immutable frozenset object initialized with elements from the given iterable.

This data type supports methods like copy(), difference(), intersection(), isdisjoint(), issubset(), issuperset(), symmetric_difference() and union(). Being immutable, it does not have methods that add or remove elements.

Syntax:

frozenset([iterable])
# Example:

# Frozensets
# initialize A and B
A = frozenset([1, 2, 3, 4])
B = frozenset([3, 4, 5, 6])
A.isdisjoint(B) # ā–¶ False āˆµ they have common intersection points
False
A.difference(B) # ā–¶ frozenset({1, 2})
frozenset({1, 2})
A | B           # ā–¶ frozenset({1, 2, 3, 4, 5, 6})
frozenset({1, 2, 3, 4, 5, 6})
A.add(3)        # ā–¶ Error!
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-21-bc9e07fcbe69> in <module>
----> 1 A.add(3) # Output: Error!

AttributeError: 'frozenset' object has no attribute 'add'

Frozenset methods#

This data type supports methods like copy(), union(), intersection(), difference(), and symmetric_difference(). Being immutable, it does not have methods that add or remove elements.

# Example 1: Frozensets

# initialize A and B
A = frozenset([1, 2, 3, 4])
B = frozenset([3, 4, 5, 6])

# copying a frozenset
C = A.copy()                     # ā–¶ frozenset({1, 2, 3, 4})
print(C)

# union
print(A.union(B))                # ā–¶ frozenset({1, 2, 3, 4, 5, 6})

# intersection
print(A.intersection(B))         # ā–¶ frozenset({3, 4})

# difference
print(A.difference(B))           # ā–¶ frozenset({1, 2})

# symmetric_difference
print(A.symmetric_difference(B)) # ā–¶ frozenset({1, 2, 5, 6})
frozenset({1, 2, 3, 4})
frozenset({1, 2, 3, 4, 5, 6})
frozenset({3, 4})
frozenset({1, 2})
frozenset({1, 2, 5, 6})

Other Frozenset methods#

Similarly, other set methods like isdisjoint(), issubset(), and issuperset() are also available.

# Example 2: Frozensets

# initialize A, B and C
A = frozenset([1, 2, 3, 4])
B = frozenset([3, 4, 5, 6])
C = frozenset([5, 6])

# isdisjoint() method
print(A.isdisjoint(C))  # ā–¶ True

# issubset() method
print(C.issubset(B))    # ā–¶ True

# issuperset() method
print(B.issuperset(C))  # ā–¶ True
True
True
True