Set is a collection of items. Apart from sets, three other data types used as collection of data are List, Tuple and Dictionary. We have already learnt about the other three and will go through sets in this chapter.

## Why Sets?

Just like lists, tuples and dictionaries, sets are also used to store data. So, why a new data type? What makes sets different from lists and tuples is that a set can’t store duplicate data. For example, a list can have an element more than once, whereas a set can have an element only once.

A set in Python is similar to the set about which we talk in our day-to-day life. For example, a set of books, a set of movies, a set of students. We know that a set of students can’t have a student more than once. Thus, a set of students consists of the names of unique students. Similarly, a set of movies consists of the names of unique movies.

Therefore, sets are used when we want to store unique data.

## Creating a Python Set

The items/elements in a set are enclosed within braces `{ }`

and separated by commas. The elements can be of the same or different data types.

```
myset = {1, 2, 3}
print(myset)
```

In the above example, `myset`

is a set having three elements of type integer.

```
myset = {1, 2, 3, "Hello"}
print(myset)
```

In the above example, `myset`

is a set having elements of different data types.

An empty set is defined using the `set()`

function as shown below.

```
myset = set()
print(myset)
```

## Properties of Python Set

### Each element in a set is unique

There can’t be duplicates of any element present in a set.

```
myset = {1, 2, 3, 2}
print(myset)
```

We assigned the element 2 twice in the set but it got discarded.

### A set is unordered

Elements in a set don’t have a specific order. Their order can get changed every time you use them.

Consider the following code.

```
myset = {1, 2, 3, "1", "Hello"}
print(myset)
```

On running it, we got a different result each time. For example, we got the following result on running it the first time.

`{1, 2, 3, 'Hello', '1'}`

On running the second time, we got the following result.

`{'Hello', 1, 2, 3, '1'}`

This is also the reason why we can’t access elements of a set through index or position.

### Elements of a set are immutable

If a data type is immutable, it means that its elements can’t be added or deleted. Examples of immutable data types are int, float, bool, string and tuple. Examples of mutable data types are list, dictionary and set.

Therefore, lists, dictionaries or sets can’t be elements of a set.

The following set is valid.

```
myset = {1, 2, 3.2, "1", "Hello", (10, 20)}
print(myset)
```

The following set is invalid because it contains a list which is mutable.

```
myset = {1, 2, 3.2, "1", "Hello", [10, 20]}
print(myset)
```

### Sets are mutable

The elements of a set can be added or deleted.

## Adding Elements to Python Set

We can add new elements to a set using the following functions.

### Python add()

The `add()`

function adds a single element to a set.

```
myset = {1, 2, 3}
myset.add(5)
print(myset)
```

`myset.add(5)`

added 5 to the set `myset`

.

### Python update()

The `update()`

function takes lists, strings, tuples and other sets as an argument and adds the elements in the passed arguments to the set.

```
myset = {1, 2, 3}
myset.update([5, 10])
print(myset)
```

In the above example, a list `[5, 10]`

is passed to the `update()`

function. Thus, the elements of the list got appended to the set.

```
myset = {1, 2, 3}
myset.update([5, 10], [15, 20], {25, 30})
print(myset)
```

Here, since two lists and a set are passed to the `update()`

function, their elements got added to the set `myset`

.

## Deleting Elements from Python Set

### Python discard()

The `discard()`

function is used to remove a particular element from a set.

```
colors = {"Blue", "Green", "Red", "Orange", "Yellow", "Brown"}
colors.discard("Green") # removing "Green" from set
print(colors)
```

`colors.discard("Green")`

removed "Green" from the set `colors`

.

If we try to remove an element which is not present in the set, `discard()`

doesn’t throw an error.

```
colors = {"Blue", "Green", "Red", "Orange", "Yellow", "Brown"}
colors.discard("Violet")
print(colors)
```

"Violet" is not present in the set, still trying to remove it didn’t throw any error.

### Python remove()

The `remove()`

function is used to remove a particular element from a set. It differs from `discard()`

as it throws the “**KeyError**” if we try to remove an element which is not present in the set.

```
colors = {"Blue", "Green", "Red", "Orange", "Yellow", "Brown"}
colors.remove("Green") # removing "Green" from set
print(colors)
```

`colors.remove("Green")`

removed "Green" from the set.

If we try to remove an element which is not present in the set, `remove()`

throws the “**KeyError**” as shown below.

```
colors = {"Blue", "Green", "Red", "Orange", "Yellow", "Brown"}
colors.remove("Violet")
```

### Python pop()

For sets, the `pop() `

function behaves differently because we can’t remove an element by index. This function removes an element randomly and returns the removed element.

```
colors = {"Blue", "Green", "Red", "Orange", "Yellow", "Brown"}
colors.pop()
print(colors)
```

In the above example, `pop()`

selected a random element and removed it from the set.

### Python clear()

The `clear()`

function removes all the elements from a set.

```
colors = {"Blue", "Green", "Red", "Orange", "Yellow", "Brown"}
colors.clear() # removing all element from set
print(colors)
```

## Python Set Operations

Some mathematical operations like union, intersection, difference and symmetric difference on sets can be implemented on Python sets as well. For that, consider the two sets s1 and s2 on which we will be performing the operations.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
```

### Python Set Union

Union of sets s1 and s2 is a new set having all the elements of both the sets.

Union can be performed using the `|`

operator.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1 | s2)
```

Union can also be performed using the `union()`

function.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1.union(s2))
print(s2.union(s1))
```

### Python Set Intersection

Intersection of sets s1 and s2 is a new set having the common elements of both the sets.

Intersection can be performed using the `&`

operator.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1 & s2)
```

4, 5 and 6 are present in both the sets and hence constitutes the intersection set `s1 & s2`

.

Intersection can also be performed using the `intersection()`

function.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1.intersection(s2))
print(s2.intersection(s1))
```

### Python Set Difference

Difference of set s1 from set s2 is a new set having the elements which are present in s1 and not in s2.

Difference can be performed using the `-`

operator.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1 - s2)
print(s2 - s1)
```

Set `s1 - s2`

consists of the elements present in s1 but not in s2, and set `s2 - s1`

consists of the elements present in s2 but not in s1.

Difference can also be performed using the `difference()`

function.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1.difference(s2))
print(s2.difference(s1))
```

`s1.difference(s2)`

is equivalent to `s1 - s2`

and `s2.difference(s1)`

is equivalent to `s2 - s1`

.

### Python Set Symmetric Difference

Symmetric Difference of sets s1 and s2 is a new set having the elements in s1 and s2 but not the common elements in both. It can be seen as (union - intersection).

Difference can be performed using the `^`

operator.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1 ^ s2)
```

Symmetric difference can also be performed using the `symmetric_difference()`

function.

```
s1 = {1, 2, 3, 4, 5, 6}
s2 = {4, 5, 6, 7, 8}
print(s1.symmetric_difference(s2))
print(s2.symmetric_difference(s1))
```

### Python Set Membership Test

We can test if an element is present in a set using the membership operators `in`

and `not in`

.

```
myset = {1, 2, "Blue", "Green"}
print(2 in myset)
print(4 in myset)
print("Green" not in myset)
```

## Iteration Through a Python Set

We can iterate through a set using a `for`

loop.

```
colors = {"Blue", "Green", "Red"}
for color in colors:
print(color)
```

A variable `color`

goes to each element in the set `colors`

and takes its value, and that value is printed on the screen.

## Different Ways to Create a Python Set

We already know how to create a set.

An empty set is created as follows.

`myset = set()`

A set having elements is created as follows.

`myset = {1, 2, 3, 4}`

Sets can also be created using the `set()`

function. This function converts a sequence (list, string, tuple) or a collection(dictionary, set) into a set.

In the following example, a list, a string and a set are converted to sets.

```
set1 = set([1, 2, 3]) # list is converted to set
set2 = set("Codesdope") # string is converted to set
set3 = set((1, 2, 3, 4)) # set is converted to set
print(set1)
print(set2)
print(set3)
```

## Python Copying Set

Let’s look at the different ways we can copy a set.

### Simple Assignment

A set can be copied to a variable by simply assigning it to the variable.

```
set1 = {1, 2, 3, 4}
set2 = set1
print(set2)
```

Here, the set stored in the variable `set1`

is assigned to the variable `set2`

. Thus, both the variables store the same set. As a result, if some change is made in `set2`

, it will also get reflected in `set1`

, which is often undesirable.

Let’s see how a change in set2 is getting reflected in set1.

```
set1 = {1, 2, 3, 4}
set2 = set1
set2.add(10)
print("Original set:", set1)
print("New set:", set2)
```

On changing `set2`

, `set1`

also got changed. This is because both the variables are pointing to the memory location of the same set.

To prevent this, we can use the copy() function.

### Python copy()

`copy()`

is used to create a shallow copy of a set.

```
set1 = {1, 2, 3, 4}
set2 = set1.copy()
set2.add(10)
print("Original set:", set1)
print("New set:", set2)
```

In this example, a shallow copy of `set1`

is created using `copy()`

and that copy is assigned to `set2`

. As a result, modifying `set2`

didn’t modify `set1`

because now the variables are pointing to the memory addresses of different sets.

### Python set()

A set can be copied by passing it to the `set()`

function.

```
set1 = {1, 2, 3, 4}
set2 = set(set1)
set2.add(10)
print("Original set:", set1)
print("New set:", set2)
```

We created a new set having all the elements of `set1`

using `set(set1)`

and assigned this newly created set to `set2`

.

## Built-in Functions in Python for Set

The functions available in Python which can be used with sets are shown below.

### len()

It returns the number of elements in a set.

```
myset = {1, 2, 3, 4, 5, 6}
print(len(myset))
```

### max()

It returns the element from a set that has the maximum value.

```
myset = {3, 2, 1, 5, 6, 4}
print(max(myset))
```

### min()

It returns the element from a set that has the minimum value.

```
myset = {3, 2, 1, 5, 4}
print(min(myset))
```

### sum()

It returns the sum of all the elements in a set.

```
myset = {3, 2, 1, 5, 6, 4}
print(sum(myset))
```

### sorted()

It returns a sorted list from the set.

```
myset = {3, 2, 1, 5, 6, 4}
print(sorted(myset))
```

To sort the elements in descending order, pass another argument `reverse=True`

to the `sorted()`

function.

```
myset = {3, 2, 1, 5, 6, 4}
print(sorted(myset, reverse=True))
```

### any()

It returns True if any of the elements in a set are True. Otherwise, it returns False.

```
myset = {3, 2, 1, True}
print(any(myset))
```

`any(mytuple)`

returned True because all the elements of the set are non-zero or True.

Look at another example where one element of the set is False.

```
myset = {3, 2, 1, False}
print(any(myset))
```

In the above example, one element of the set is False, but still the `any()`

function returned True. This is because if atleast one element is non-zero or True, then the function returns True.

### all()

It returns True if all the elements in a set are True. Otherwise, it returns False.

```
myset = {3, 2, 1, True}
print(all(myset))
```

```
myset = {3, 2, 1, False}
print(all(myset))
```

In this example, one element is False and so the `all()`

function returned False.

## Other Set Functions

We have already looked at some of the set functions like add(), discard(), remove(), pop(), clear(), union(), intersection(), difference(), symmetric_difference() and copy(). Other useful functions are shown below.

### Python isdisjoint()

It returns True if two sets are disjoint. Two sets are disjoint if they have no common element.

```
set1 = {1, 2, 3, 4, 5}
set2 = {6, 7, 8}
print(set1.isdisjoint(set2))
print(set2.isdisjoint(set1))
```

`isdisjoint()`

function returned True in this example because both the sets don’t have any common element.

### Python intersection_update()

It calculates the intersection of two or more sets and assigns the result to the set which calls the function.

Look at the following example to understand the concept better.

```
set1 = {1, 2, 3, 4, 5, 6}
set2 = {4, 5, 6, 7, 8}
set1.intersection_update(set2)
print('set1:', set1)
print('set2:', set2)
```

`set1.intersection_update(set2)`

- the `intersection_update()`

function assigned the intersection set {4, 5, 6} of sets `set1`

and `set2`

to `set1`

because `set1`

called the function.

We can also pass more than one set to this function as shown below.

```
set1 = {1, 2, 3, 4, 5, 6}
set2 = {4, 5, 6, 7, 8}
set3 = {2, 5, 6, 8}
result = set1.intersection_update(set2, set3)
print('intersection_update result:', result)
print('set1:', set1)
print('set2:', set2)
print('set3:', set3)
```

Here, the intersection set of sets `set1`

, `set2`

and `set3`

is assigned to `set3`

.

### Python difference_update()

It calculates the difference of one set from another and assigns the result to the set which calls the function.

Look at the following example.

```
set1 = {1, 2, 3, 4, 5, 6}
set2 = {4, 5, 6, 7, 8}
set1.difference_update(set2)
print('set1:', set1)
print('set2:', set2)
```

The `difference_update()`

function assigned the difference set {1, 2, 3} to `set1`

because it called the function.

### Python symmetric_difference_update()

It calculates the symmetric difference of one set from another and assigns the result to the set which calls the function.

```
set1 = {1, 2, 3, 4, 5, 6}
set2 = {4, 5, 6, 7, 8}
set1.symmetric_difference_update(set2)
print('set1:', set1)
print('set2:', set2)
```

The `symmetric_difference_update()`

function assigned the symmetric difference set {1, 2, 3, 7, 8} to `set1`

because it called the function.

### Python issubset()

It returns True if a set is a subset of another set, otherwise it returns False. A set `set1`

is a subset of set `set2`

if all the elements of a `set1`

are present in `set2`

.

```
set1 = {4, 5, 6}
set2 = {4, 5, 6, 7, 8}
print(set1.issubset(set2)) # is set1 subset of set2?
print(set2.issubset(set1)) # is set2 subset of set1?
```

All the elements of `set1`

are present in `set2`

and thus set1 is a subset of `set2`

. Whereas, `set2`

doesn’t have all its elements in `set1`

and so `set2`

is not a subset of `set1`

.

### Python issuperset()

It returns True if a set is a superset of another set, otherwise it returns False. A set `set1`

is a superset of set `set2`

if set1 has all the elements of `set2`

.

```
set1 = {4, 5, 6}
set2 = {4, 5, 6, 7, 8}
print(set1.issuperset(set2)) # is set1 superset of set2?
print(set2.issuperset(set1)) # is set1 superset of set2?
```

`set1`

doesn’t have all the elements of `set2`

and thus `set1`

is not a superset of `set2`

, `set2`

is a superset of `set1`

.

## Python Frozenset

Frozenset is an immutable variant of set. Sets are mutable and so elements can be added or deleted to sets. Whereas, frozensets are immutable and so their elements can’t be modified once assigned.

A frozenset can be created using the `frozenset()`

function. Like `set()`

, `frozenset()`

also converts a sequence (list, string, tuple) or a collection(dictionary, set) into a frozenset.

The following example creates three frozensets from a list, a string and a set.

```
frozenset1 = frozenset([1, 2, 3]) # list is converted to frozenset
frozenset2 = frozenset("Codesdope") # string is converted to frozenset
frozenset3 = frozenset((1, 2, 3, 4)) # set is converted to frozenset
print(frozenset1)
print(frozenset2)
print(frozenset3)
```

All the functions which can be used with sets can also be used with frozensets, except for those functions which modify the elements. For example, functions like `add()`

, `update()`

, `remove()`

, etc, can’t be used with frozensets.

In the next example, adding an element to a frozenset with `add()`

results in an error.

```
frozenset1 = frozenset([1, 2, 3])
frozenset1.add(4)
print(frozenset1)
```

Let’s look at some more examples.

```
frozenset1 = frozenset({1, 2, 3})
frozenset2 = frozenset({2, 3, 4, 5, 6})
print(len(frozenset1)) # prints no. of elements of frozenset1
print(sum(frozenset1)) # prints sum of elements of frozenset1
print(frozenset2.intersection(frozenset1)) # prints intersection of frozenset1 and frozenset2
print(frozenset2.issuperset(frozenset1)) # prints if frozenset1 is superset of frozenset2
```

### When Should We Use a Frozenset?

We know that the elements of a frozenset can’t be changed and no more elements can be added or deleted from it. Therefore, it can be used to store the data we don’t want the user to change. For example, suppose we have finalized some students in a group. In that case, we can use a frozenset to store the names of those students, so that no one can add, delete or modify their names.

If in this group of students, we don’t want to change the names of the students but want to have the flexibility to add new students or delete existing students from the group, then we should use a set instead.

So now we have learned about all the built-in data types in Python. We have gone through some examples in the course but it is important that you practice questions from the practice section, because the more you practice the better you will understand the concept. In the next section, you are going to make your own functions.