## Introduction

A set is an unordered collection of unique elements which are unindexed. Sets are mutable which means they can be modified in-place without creating a new object. However, set items must be of immutable types such as strings, numbers or tuples.

## Defining a Set

A set can be created as a sequence of comma-separated values enclosed within a pair of curly braces {}. The following example demonstrates that sets are unordered, i.e. order of the elements is inconsequential.

EXAMPLE Sets are unordered.

1set1 = {23, 85, 41, 19, 22}
2set2 = {41, 22, 85, 23, 19}
3set1 == set2

True


We sometimes say that sets are unindexed. That is, set items cannot be referred to by an index or a key.

EXAMPLE Sets are unindexed.

1set1 # error: we cannot refer to a set item using an index.

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_4056/2116443343.py in <module>
----> 1 set1 # error: we cannot refer to a set item using an index.

TypeError: 'set' object is not subscriptable


We can get the unique values of a list (or a tuple) by using the set() constructor.

EXAMPLE set() constructor.

1list1 = [2, 4, 6, 6, 8, 8, 8, 9]
2set3 = set(list1)
3set3

{2, 4, 6, 8, 9}


We can get the length of a set using the len() function.

EXAMPLE Length of a set using len().

1len(set3)

5


EXAMPLE Set items must be immutable.

1set4 = {2, 4, 6, "string", (8, 9, 10), 2.4}
2set4

{(8, 9, 10), 2, 2.4, 4, 6, 'string'}


## List vs Tuple vs Dictionary vs Set

Before we proceed, let’s summarize the key properties of the data structures we have learnt so far.

Data Structure Ordered Indexed Mutable Example
List ✔️ ✔️ ✔️ [1,2,3]
Tuple ✔️ ✔️ (1,2,3)
Dictionary ✔️ ✔️ {'a':1 , 'b':2, 'c':3}
Set ✔️ {1,2,3}

As we can see, even though sets are both unindexed and unordered, they are mutable.

## Modifying a Set

Sets are mutable. However, we cannot access or change an element of a set using indexing or slicing since it is unindexed. But we can still add or remove items from a set.

To add one item to a set, we use the add() method.

EXAMPLE Adding an item to a set.

1fruits = {'apple', 'orange', 'banana', 'pineapple'}
3fruits

{'apple', 'banana', 'orange', 'pineapple', 'strawberry'}


We use the update() method to add items from one set to another set.

EXAMPLE Adding more than one item to a set.

1moreFruits = {"durian", "pear"}
2fruits.update(moreFruits)
3fruits

{'apple', 'banana', 'durian', 'orange', 'pear', 'pineapple', 'strawberry'}


If there are duplicate items in the second set, the update() method will take the union of the items from both sets and update the first set.

EXAMPLE update() method will remove duplicates.

1set1 = {1, 2, 3, 4}
2set2 = {2, 4, 6, 8}
3set1.update(set2)
4set1

{1, 2, 3, 4, 6, 8}


We use the remove() method to remove an item from a set.

EXAMPLE Remove an item from a set.

1fruits.remove("durian")
2fruits

{'apple', 'banana', 'orange', 'pear', 'pineapple', 'strawberry'}


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

EXAMPLE Remove all items from a set.

1fruits.clear()
2fruits

set()


## Mathematical Set Operations

The union() method is very similar to the update() method. They both produce the same results. There is a subtle difference however. The union method does not modify the original set. Instead, a new set object is created.

EXAMPLE union() method.

1set1 = {1, 2, 3, 4}
2set2 = {2, 4, 6, 8}
3print(set1.union(set2))
4print(set1)

{1, 2, 3, 4, 6, 8}
{1, 2, 3, 4}


To store the result, you need to assign a variable to the new object.

1a = set1.union(set2)
2a

{1, 2, 3, 4, 6, 8}


The intersection() method produces the intersection of two sets $A$ and $B$, which is a set of elements that are common to both sets.

EXAMPLE intersection() method.

1A = {1, 2, 3, 4, 5}
2B = {4, 5, 6, 7, 8}
3print(A.intersection(B)) # intersection method syntax
4print(A & B) # alternative syntax

{4, 5}
{4, 5}


A slightly different method is the intersection_update() method that produces the same results as the intersection() method but with set $A$ updated.

EXAMPLE intersection_update() method.

1A = {1, 2, 3, 4, 5}
2B = {4, 5, 6, 7, 8}
3A.intersection_update(B)
4A

{4, 5}


The difference of two sets $(A - B)$ is the set of all elements of $A$ that are not in $B$. This is accomplished using the difference() method or the alternative syntax A - B.

EXAMPLE difference() method.

1A = {1, 2, 3, 4, 5}
2B = {2, 5}
3print(A.difference(B)) # difference method syntax
4print(A - B) #  alternative syntax

{1, 3, 4}
{1, 3, 4}


A slightly different method is the difference_update() method that produces the same results as the difference() method but with set $A$ updated.

EXAMPLE difference_update() method.

1A = {1, 2, 3, 4, 5}
2B = {2, 5}
3A.difference_update(B)
4A

{1, 3, 4}


The issubset() method applied to two sets $A$ and $B$ as A.issubset(B) returns True if $A$ is a subset of $B$. That is, all elements of $A$ are present in $B$. Otherwise, it returns False.

EXAMPLE issubset() method.

1A = {1, 2, 3, 4, 5}
2B = {2, 5}
3B.issubset(A) # Is B a subset of A?

True


The issuperset() method applied to two sets $A$ and $B$ as A.issuperset(B) returns True if $A$ is a superset of $B$. That is, all elements of $B$ are present in $A$. Otherwise, it returns False.

EXAMPLE issuperset() method.

1A = {1, 2, 3, 4, 5}
2B = {2, 5}
3A.issuperset(B) # Is A a superset of B?

True


The isdisjoint() method returns True if 2 sets have no elements in common. Otherwise, it returns False.

EXAMPLE isdisjoint() method.

1A = {1, 3}
2B = {2, 5}
3A.isdisjoint(B) # Are A and B disjoint?

True


The following table summarizes all set methods.

Method Description
add() Adds an element to the set.
clear() Adds an element to the set.
copy() Returns a copy of the set.
difference() Returns the difference of two or more sets as a new set.
difference_update() Removes all elements of another set from this set.
discard() Removes an element from the set if it is a member.
intersection() Returns the intersection of two sets as a new set.
intersection_update() Updates the set with the intersection of itself and another.
isdisjoint() Returns True if two sets have a null intersection.
issubset() Returns True if another set contains this set.
issuperset() Returns True if this set contains another set.
remove() Removes an element from the set. Raises KeyError if element not present.
union() Returns the union of sets in a new set.
update() Updates the set with the union of itself and others.