Sets in Python

In this tutorial, I am going to discuss about **Set datatype in python**, different operations which can be performed on sets and built-in functions available in python for sets.

## Sets in Python

**Set in python** is an unordered collection of elements. It is similar to lists in python but unlike lists every set element must be unique and immutable object. Although set itself is a mutable object i.e. we can add or remove any element from a set.

### Creating a Set

A set is a collection of immutable python objects separated by commas and enclosed within curly braces { }. **Set datatype in python** is same as sets we use in mathematics, we can also perform set operations like union, intersection etc. on python sets.

Following is an example of a set in python :

set1 = { 'a', 1, 'b', 2 }

Expression | Description |
---|---|

S1 = set() | Empty set |

S2 = {0, 1, 2, 3} or {'a','b','c','d'} | Simple declaration of a set with 4 values |

S3 = set('Learn Python Coding') | set of an iterable item |

S4 = set(range(3,7)) | Set of successive integers from -5 to 6 |

The first declaration is an empty set. As set and dictionary both use curly braces in python so if we use empty curly braces python takes it as an empty dictionary instead of an empty set.

So instead of empty curly braces empty set() constructor is used to declare an empty set.

The second declaration is a simple set declaration with all elements of same datatypes.

The third and fourth declaration shows how to create a set using an iterable python object. Since a set cannot contain a mutable object, it is not possible to create a nested set i.e. set within a set.

Let's see some examples on creating a sets.

```
set1 = {1,2,3,4,5}
print("Simple set : ", set1)
set2 = set("Coding is Fun")
print("Set using an iterable : ",set2)
set3 = set(range(1,8))
print("Set from range() function ", set3)
```

```
Simple set : {1, 2, 3, 4, 5}
Set using an iterable : {'d', 'F', 'g', 'u', 'n', 'i', 'o', 'C', ' ', 's'}
Set from range() function {1, 2, 3, 4, 5, 6, 7}
```

```
setl = {1,2,[3,4]}
print(setl)
```

```
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
< ipython-input-40-8bb123d918ff > in < module >
----> 1 setl = {1,2,[3,4]}
2 print(setl)
TypeError: unhashable type: 'list'
```

As we can see in the above example, if we try to add a mutable object (list, dictionary or set) as an element to a set then python throws a TypeError.

### Accessing a Set in Python

**A set in python** is an unordered collection which means we cannot know the order of elements of a set. That is why set is also unindexed which means we cannot use indexing operator to access individual element from a set. Hence we have to access a complete set at a time.

Let's see how to access a set in python :

```
a = {1,3,2}
b = {5,9,2,2,5,1,0}
print("Accessing set 'a' : ", a)
print("Accessing set 'b' : ", b)
print(b[3])
```

```
Accessing set 'a' : {1, 2, 3}
Accessing set 'b' : {0, 1, 2, 5, 9}
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
< ipython-input-39-e6813b12f5b6 > in < module >
3 print("Accessing set 'a' : ", a)
4 print("Accessing set 'b' : ", b)
----> 5 print(b[3])
TypeError: 'set' object is not subscriptable
```

In the above example,set reorders the elements in ascending order, also in the set *b* the duplicate elements are removed and then reordered in ascending order.

If we try to access an individual element from a set using indexing then we will face TypeError.

### Traversing through a Set

We know that traversing means accessing and processing each element of the sequence which can be done by using loops in python.

Even though we cannot access individual elements of set using indexing we can still use loops to traverse through a list if we want to access and process each element of a set.

For Example the below shown example **prints each element of a set in python**.

```
set1 = {1,2,3,4,5}
for val in set1 :
print(val)
```

```
1
2
3
4
5
```

So, we can access and process each element of a set using loops.

## Python Set Operations

Just like mathematical sets we can also perform set operations like union, intersection, difference and other. We can use operators or methods to perform these operations on sets. Let's see operations that can be performed on sets in python.

### Set Union

Union is a set operation in which all elements of two sets are combined to from a new set.

If both sets have some common elements then the new set will contain only one instance of the element

A union is performed using **|** operator and we can also perform this using `union()`

method.

Let's see some examples :

```
A = {'a','b','c','d','e'}
B = {'d','e','f','g','h'}
print("set A = ",A)
print("set B = ",B)
print("Using | operator - ",A | B)
print("Using union() method - ", A.union(B))
```

```
set A = {'e', 'b', 'a', 'd', 'c'}
set B = {'f', 'h', 'e', 'd', 'g'}
Using | operator - {'e', 'b', 'f', 'h', 'd', 'a', 'g', 'c'}
Using union() method - {'e', 'b', 'f', 'h', 'd', 'a', 'g', 'c'}
```

### Set Intersection

Intersection is a set operation in which all the common elements from two sets are combined to create a new set.

Intersection is performed using **&** operator and we can also perform this using `intersection()`

method.

Let's see some examples of **set intersection in python** :

```
print("set A = ",A)
print("set B = ",B)
print("Using & operator - ",A & B)
print("Using intersection() method - ", A.intersection(B))
```

```
set A = {'e', 'b', 'a', 'd', 'c'}
set B = {'f', 'h', 'e', 'd', 'g'}
Using & operator - {'d', 'e'}
Using intersection() method - {'d', 'e'}
```

### Set Difference

**Set difference** is set operation in which the elements from the first set which are not present in second set form the new set.

Difference from set B from set A (A - B) has all the elements of set A which are not present in set B. Set Difference is performed using **-** operator and it can also be performed using `difference()`

method.

Let's see some examples of **set difference in python**:

```
print("set A = ",A)
print("set B = ",B)
print("Using - operator : A - B = ",A - B)
print("Using difference() method : A - B = ", A.difference(B))
print("Using - operator : B - A = ",B - A)
```

```
set A = {'e', 'b', 'a', 'd', 'c'}
set B = {'f', 'h', 'e', 'd', 'g'}
Using - operator : A - B = {'b', 'c', 'a'}
Using difference() method : A - B = {'b', 'c', 'a'}
Using - operator : B - A = {'h', 'g', 'f'}
```

### Set Symmetric Difference

**Set symmetric difference** is set operation in which the elements which are in first set but not in second set and are in second set but not in first set are combined to form a new set.

Symmetric difference between two sets A and B means elements of set A which are not in set B and elements of set B which are not in set A.

Set symmetric difference can be performed using **^** operator and it can also bee performed using `symmetric_difference()`

method.

```
print("set A = ",A)
print("set B = ",B)
print("Using ^ operator : A ^ B = ",A ^ B)
print("Using symmetric_difference() method : A ^ B = ", A.symmetric_difference(B))
print("Using ^ operator : B ^ A = ",B ^ A)
```

```
set A = {'e', 'b', 'a', 'd', 'c'}
set B = {'f', 'h', 'e', 'd', 'g'}
Using ^ operator : A ^ B = {'g', 'b', 'f', 'h', 'c', 'a'}
Using symmetric_difference() method : A ^ B = {'g', 'b', 'f', 'h', 'c', 'a'}
Using ^ operator : B ^ A = {'g', 'f', 'b', 'c', 'a', 'h'}
```

### Membership Operation

Just like strings, lists, tuples and dictionaries support membership operators **in** and **not in** the sets also support membership operators.

These operators are used to check if given element is present in the set.

Let's see use of these operators with **set in python**.

`print( 'a' in {'a','b','c'})`

`True`

`print( 7 not in {1,3,5,7,9})`

`False`

## Set Methods in Python

Python also provides methods for set manipulation and set operations. These built-in methods help us process and manipulate sets more easily.

Following is a list of methods provided in python for set manipulation along with small description about each of them.

Method() | Description |
---|---|

`add()` |
Add an element to the end of set |

`clear()` |
Removes all items from the set |

`copy()` |
Returns a true copy of the set |

`difference()` |
Returns the difference of two or more sets as a new set |

`difference_update()` |
Removes all elements of a set from the given set |

`discard()` |
Removes an element from a set if it is a member of the set |

`intersection()` |
Returns the intersection of two sets as a new set |

`intersection_update()` |
Updates a set with intersection between the set and another set |

`isdisjoint()` |
Returns true if two sets have no common elements |

`issubset()` |
Returns true if another set contains all elements of a set |

`issuperset()` |
Returns true if a set contains all the elements of another set |

`pop()` |
Returns and removes an arbitrary element from a set |

`remove()` |
Removes an element given as argument from the set |

`symmetric_difference()` |
Returns symmetric difference between two sets as a new set |

`symmetric_difference_update()` |
Updates a set with symmetric difference between the set and another set |

`union()` |
Returns union of two sets as a new set |

`update()` |
Updates a set with union of the set and set given as argument |

Some examples of **Python set methods** :

```
set_ex = { 1,2,3,4,5 }
set_ex.add(6)
print("add() method : ",set_ex)
print("issuperset() method : set_ex.issuperset({1,2}) = ",set_ex.issuperset({1,2}))
print("isdisjoint() method : set_ex.isdisjoint({9,8}) = ",set_ex.isdisjoint({9,8}))
print("pop() method : ",set_ex.pop(),", set = ",set_ex)
```

```
add() method : {1, 2, 3, 4, 5, 6}
issuperset() method : set_ex.issuperset({1,2}) = True
isdisjoint() method : set_ex.isdisjoint({9,8}) = True
pop() method : 1 , set = {2, 3, 4, 5, 6}
```

We will learn about these functions as we learn in further articles with more examples.

## Set Manipulation

So till now, we have seen creating and accessing set, operations on sets and built-in methods for set in python.

Before we go ahead, you should note that sets in python are **mutable** objects which means that we can add elements to a set and remove elements from a set.

Now, we will discuss other set manipulations which are **append** elements to a set and **delete** operation on a set.

Let's learn about **set manipulation in python**.

### Appending Elements to a Set

There are two built-in methods provided by python `add()`

and `update()`

.

The `add()`

method takes an immutable python object as argument and appends it to the set.

The `update()`

method takes an iterable python object as argument and appends all the elements of the iterable to the set.

Let's see some examples :

```
set_ex1 = {1,2}
print("Original set : ", set_ex1)
set_ex1.update({3,4})
print("Using update() method : ",set_ex1)
set_ex1.add(9)
set_ex1.add('a')
print("Using add() method : ",set_ex1)
```

```
Original set : {1, 2}
Using update() method : {1, 2, 3, 4}
Using add() method : {1, 2, 3, 4, 9, 'a'}
```

### Deleting Elements from a Set

As sets are mutable, we are able to delete elements from a set or we can also delete a set completely.

This can be done using built-in set methods `pop()`

, `discard()`

and `remove()`

.

The `discard()`

and `remove()`

methods are pretty much the same, they both take an immutable python object which might be a set element as argument and then updates the set by removing that element.

The main difference between `discard()`

and `remove()`

is that `discard()`

method does not give any error if the argument is not present in the set and `remove()`

method throws KeyError.

The `pop()`

method does not take any argument, it removes and returns an element of the set from starting of the set and raises KeyError if the set is empty.

```
set_ex2 = {1,2,3,4}
print("Original set", set_ex2)
set_ex2.remove(1)
print("Set after remove() : ",set_ex2)
set_ex2.discard(2)
print("Set after discard() : ", set_ex2)
print("pop() method :",set_ex2.pop())
print("Set after pop() : ",set_ex2)
```

```
Original set {1, 2, 3, 4}
Set after remove() : {2, 3, 4}
Set after discard() : {3, 4}
pop() method : 3
Set after pop() : {4}
```

## Frozen Set

We know that in python everything is an object, and thus each object has its class. Just like set objects, python also have frozenset objects from frozenset class.

In simple words, frozen set is an immutable set, just like a tuple is an immutable list. We can perform various set operations on frozenset except appending elements and deleting elements. Frozensets can be created using ** frozenset()** method.

As we discussed frozenset objects support operations like `union()`

, `intersection()`

, `difference()`

, `copy()`

, `isdisjoint()`

, `issuperset()`

, `issubset()`

and `symmetric_difference()`

. Slice these are immutable sets they do not support methods like add or remove which update the set itself.

Let's see some examples involving **frozensets in python** :

```
A = frozenset(['a','b','c',1,2,3])
B = frozenset(['c','d','e',3,4,5])
print("Set A = ",A)
print("Set B = ",B)
print("A - B = ",A.difference(B))
print("A union B = ",A.union(B))
```

```
Set A = frozenset({1, 2, 'c', 3, 'a', 'b'})
Set B = frozenset({3, 4, 'c', 'e', 5, 'd'})
A - B = frozenset({1, 2, 'b', 'a'})
A union B = frozenset({1, 2, 'c', 3, 4, 'e', 5, 'd', 'a', 'b'})
```

## Conclusion

In this tutorial, we have discussed about **set datatypes in python**, accessing and traversing set, different operations on sets and methods for sets provided by python.

If you have any questions please comment below also share your views and suggestions in the comment box.