# Python Sets

This is a detailed tutorial on the Python Sets. Learn to create Sets and perform various operations on them using different methods with examples.

## Python Sets

A Set is such a collection object in Python that is unordered and unindexed. No duplicate items are allowed in a Set. They are also mutable which means we can add or remove items from a set. As the Sets are unindexed, therefore, there is no direct way to change an existing item of the set.

The elements or items of a set are written between the `{}` i.e. Curley Brackets, separated by commas. A set may contain any number of items and that too of any particular data type or mixed items of different data types. But mutable elements like Python List or Dictionary can not be added as items of a set. A Tuple can be added as the element of a Set because it is immutable.

Set is a very special Python Data Type that helps us in performing a lot of useful mathematical operations like Union, Intersection, and various Symmetric and Intersection differences. We’ll find out about all of them later on in this article.

### Creating Python Sets

You can define a new set by writing comma-separated items between the curly brackets, as already mentioned. But there’s also another way of creating a set and that is to first create a collection object like Python List or Tuple and then use the built-in method `set()` to convert them into a set object.

The following code illustrates how you can create a Python Set containing items of similar and different data types.

```#Creating Different Types of Sets

#Set of Integers
numbers = {1, 2, 3, 4, 5}

print("Set of Numbers:", numbers)

#Set of Strings
strings = {'ab', 'cd', 'ef', 'gh', 'ij'}

print("Set of Strings:", strings)

#Set of Mixed Data Types
mixed = {1, 'ab', True, (1, 1.1, "Hello")}

print("Set of Mixed Data Types:", mixed)```

Output.

```Set of Numbers: {1, 2, 3, 4, 5}
Set of Strings: {'ef', 'ij', 'gh', 'ab', 'cd'}
Set of Mixed Data Types: {(1, 1.1, 'Hello'), 'ab', True}```

Note. The order of the items in the output may vary every time because sets are unordered and you can never be sure in what order they will appear each time.

The following code illustrates that the sets can not have duplicate items and even if you’ll try to add duplicate items, only one instance of the duplicate item will be considered by the set.

```#Duplicate Items in a Sets
random = {1, 2, 2, 3, 3, 4, 5}

print("random Set:", random)```

Output.

`random Set: {1, 2, 3, 4, 5}`

Here in the following code, we’re creating sets from the Python List, Tuple & Dictionary.

```#Creating Set from a List
a_list = [1, 2, 3, 3, 4, 5, 5]
set1 = set(a_list)

#Creating Set from a Tuple
a_tuple = (1, 1, 2, 2, 3, 4, 4, 5)
set2 = set(a_tuple)

#Creating Set from a Dictionary
a_dict = {
0 : 'A',
1 : 'B',
2 : 'C',
3 : 'D',
4 : 'E'
}
set3 = set(a_dict)

#Printing sets
print("Set 1:", set1)
print("Set 2:", set2)
print("Set 3:", set3)```

Output.

```Set 1: {1, 2, 3, 4, 5}
Set 2: {1, 2, 3, 4, 5}
Set 3: {0, 1, 2, 3, 4}```

Another example below shows that TypeError will be raised if you’ll try to create a set containing mutable items. Here the list `[5, 6, 7]` is a mutable object and hence it can not be a set member.

```invalidSet = {1, 2, 3, 4, [5, 6, 7]}

print(invalidSet)```

Output.

```Traceback (most recent call last):
File "<stdin>", line 1, in <module>
invalidSet = {1, 2, 3, 4, [5, 6, 7]}
TypeError: unhashable type: 'list'```

You can also create a set of individual characters using Strings. In Python, Strings are also a collection of characters and recognized as iterables and hence the built-in function `set()` if passed a string as an argument will return a set containing individual string characters as its elements.

```#A String
name = "Gurmeet"

#Creating a set of string characters
name_chars = set(name)

print(name_chars)```

Output.

`{'u', 'G', 't', 'm', 'e', 'r'}`

### Creating an Empty Set

You can not simply create an empty set by just writing the empty curly brackets. The reason being a Python Dictionary also starts with the same symbols and hence the compiler will rather create an empty dictionary instead of an empty set.

Here comes the usage of the built-in function `set()`. This method is also known as the `set()` constructor method. You can easily create an empty dictionary by using this method without passing any argument as illustrated in the following code.

```#Difference between an Empty Python Set and an Empty Dictionary

#empty Dictionary
empty_dict = {}
print("Type of empty_dict:", type(empty_dict))

#empty Set
empty_set = set()
print("Type of empty_set:", type(empty_set))```

Output.

```Type of empty_dict: <class 'dict'>
Type of empty_set: <class 'set'>```

### Accessing or Changing Set Items

You can not either access or change a particular set element. The reason being sets are unindexed. Indexing is the way using which we are able to change or access a particular element in almost every other collection data type of python. As indexing is not possible here, therefore, we can not change or access individual set items.

In the following code, we’re trying to access the set times using indexing and you can clearly see in the output that it raises `TypeError` exception.

```#set of fruits
fruits = {'Apple', 'Banana', 'Cherry', 'Dates'}

#Indexing does not work here
#raises TypeError
print(fruits[0])```

Output.

```Traceback (most recent call last):
File "<stdin>", line 6, in <module>
print(fruits[0])
TypeError: 'set' object does not support indexing```

### Loop Through Set Elements

Although you can not access individual set items yet you can always use the Python For Loop to access one item at a time. The following code illustrates the looping through a set to access each item of a given set.

```#set of fruits
fruits = {'Apple', 'Banana', 'Cherry', 'Dates'}

#loop through fruits
for fruit in fruits:
print(fruit)```

Output.

```Dates
Apple
Cherry
Banana```

Note. You can observe in the output that the items are looped through in a different order than they actually defined set order. This again shows the unindexed and unordered property of the set.

### Check If An item Exists in a Set (Membership Test)

As a set is a collection object, so we can apply the membership operators i.e. `in` and `not in` to find out if a particular item is present in a given set or not. These operators return a boolean value i.e. `True` if a given item founds in a given set and `False` a given item does not found in a given set.

```countries = {"India", "USA", "UK", "Canada", "Japan"}

#Checking if Japan present in countries
#returns True
print("Japan" in countries)

#Checking if Italy present in countries
#returns False
print("Italy" in countries)

#Checking if the UK not present in countries
#returns False
print("UK" not in countries)

#Checking if Brazil not present in countries
#returns True
print("Brazil" not in countries)```

Output.

```True
False
False
True```

### Adding New Items in a Set

We can add a new item into using the method `add()` on a given set. Multiple items can also be inserted into at once into a given set using the method `update()`. You must provide only one item as an argument to the method `add()` while you can provide collection objects like Python List, Tuple, Strings, and other sets as an argument to the `update()` method. All the duplicates in these collection objects will be avoided and only a single value among the duplicates will be considered to be added into the set.

```#set of fruits
fruits = {'Apple', 'Banana', 'Cherry', 'Dates'}

print(fruits)

fruits.update(['Mango', 'Guava', 'Watermelon'])

print(fruits)

fruits.update(['Mango', 'Pear', 'Pear'])

print(fruits)```

The method `add()` simply added the item `Papaya` into the set of Fruits. In the second case, we’ve added three fruits, namely, `Mango`, `Guava` and `Watermelon` into the set using the method `update()`. We’ve provided the list of these three fruits as an argument to this method and then in the third case we’ve again used the `update()` method for insertion.

This time, we’ve passed a list-type argument in which there are only two fruits. `Pear` is repeated two times. As you can observe in the output, only one `Pear` is added into the set in the third case and `Mango` has not been added again to the set because sets contain unique values.

Output.

```{'Dates', 'Apple', 'Cherry', 'Papaya', 'Banana'}
{'Apple', 'Guava', 'Watermelon', 'Papaya', 'Banana', 'Dates', 'Mango', 'Cherry'}
{'Apple', 'Guava', 'Watermelon', 'Papaya', 'Banana', 'Pear', 'Dates', 'Mango', 'Cherry'}```

### Removing Set Elements

There are three different ways and four different methods for the purpose of removing items from a given set. These are described below and their usage is illustrated with the help of examples.

#### Removing a Particular Item

The Python Set `discard()` and `remove()` methods are used to remove the particular item(s) from a given set. The item to be removed has to be provided as the only argument for these methods.

There is only a minor difference between these two methods and that is the method `discard()` do not raise an Error in case the item to be removed is not actually present in the set while the `remove()` method will raise a `KeyError` in case it does not find the element to be removed in the given set.

```#set of fruits
fruits = {'Apple', 'Banana', 'Cherry', 'Dates', 'Mango', 'Papaya'}
print(fruits)

#Removing the item 'Cherry'
#Present in the fruits set
#Using the method remove()
fruits.remove('Cherry')
print(fruits)

#Removing the item 'Mango'
#Present in the fruits set
print(fruits)

#Removing the item 'Pear'
#Not Present in the fruits set
#Using the method remove()
fruits.remove('Pear')
print(fruits)

#Removing the item 'Peach'
#Not Present in the fruits set
print(fruits)```

Output.

```{'Cherry', 'Papaya', 'Mango', 'Dates', 'Apple', 'Banana'}
{'Papaya', 'Mango', 'Dates', 'Apple', 'Banana'}
{'Papaya', 'Dates', 'Apple', 'Banana'}
Traceback (most recent call last):
File "<stdin>", line 20, in <module>
fruits.remove('Pear')
KeyError: 'Pear'```

#### Removing a Random (Arbitrary) Item

The method `pop()` is used to remove a random or arbitrary item from a given Python Set. This method is also available for other collection objects like lists and dictionary. But in those data types, this method is used to remove and return a particular item. As in a set, there is no order and index, hence there is no way to determine which particular item to remove.

```#set of fruits
fruits = {'Apple', 'Banana', 'Cherry', 'Dates', 'Mango', 'Papaya'}

print(fruits)

#Removing arbitrary item
fruits.pop()

print(fruits)```

Output.

```{'Cherry', 'Papaya', 'Mango', 'Dates', 'Apple', 'Banana'}
{'Papaya', 'Mango', 'Dates', 'Apple', 'Banana'}```

#### Clearing all items to make the set Empty

The method `clear()` applied on a given set will remove all of its items.

```#set of fruits
fruits = {'Apple', 'Banana', 'Cherry', 'Dates', 'Mango', 'Papaya'}

print(fruits)

#Removing all items using clear()
fruits.clear()

print(fruits)```
```{'Cherry', 'Papaya', 'Mango', 'Dates', 'Apple', 'Banana'}
set()```

## Python Set Operations

Different mathematical operations like Union, Intersection, Difference, and Symmetric Difference can be performed on the sets. Python Operators and Set Methods are used to perform these operations.

### Union

Let’s say there are two sets, set A and B. Union of Set A and B will contain all of the elements from both of these sets, maintaining the union set items distinct and unique. The following example illustrates how you can perform the union operation on two Python Sets.

There are two methods of performing union operations on sets. The first one is by using the operator `|` and the second one is by using the set method `union()`.

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

#Union of A & B using | Operator
A_UNION_B = A | B

print("A ⋃ B:", A_UNION_B)

#Union of A & B using the union() method
A_UNION_B = A.union(B)
B_UNION_A = B.union(A)

print("A ⋃ B:", A_UNION_B)
print("B ⋃ A:", B_UNION_A)```

Output.

```A ⋃ B: {1, 2, 3, 4, 5, 6, 7, 8, 9}
A ⋃ B: {1, 2, 3, 4, 5, 6, 7, 8, 9}
B ⋃ A: {1, 2, 3, 4, 5, 6, 7, 8, 9}```

### Intersection

Intersection means the common elements in two different sets. So, if there are two sets, set A and B, the intersection of these two sets will only contain the elements that are in set A as well as in set B.

In Python, you can perform the intersection of two sets using the operator `&` and the method `intersection()` applied on a given set.

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

#Intersection of A and B using & Operator
A_INTERSECT_B = A & B

print("A ⋂ B:", A_INTERSECT_B)

#Intersection of A and B using the intersection() method
A_INTERSECT_B = A.intersection(B)
B_INTERSECT_A = B.intersection(A)

print("A ⋂ B:", A_INTERSECT_B)
print("B ⋂ A:", B_INTERSECT_A)```

Output.

```A ⋂ B: {4, 5, 6}
A ⋂ B: {4, 5, 6}
B ⋂ A: {4, 5, 6}```

### Set Difference

If there are two sets, A and B, then the difference between the set B from set A i.e. `A - B` will be a set containing all the items that are only present in set A and not in set B. Similarly, the difference between set A from set B i.e. `B - A` will be a set containing all the items that are only present in set B and not in set A.

Again, there are two ways to find the set difference in python. The first way is to use the `-` operator and the second way is to use the method `difference()` on a given set.

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

#Differnce of Set B from Set A
#Using - operator
print(A - B)

#Differnce of the Set A from Set B
#Using - operator
print(B - A)

#Differnce of Set B from Set A
#Using the method difference()
print(A.difference(B))

#Differnce of the Set A from Set B
#Using the method difference()
print(B.difference(A))```

Output.

```{1, 2, 3}
{8, 9, 7}
{1, 2, 3}
{8, 9, 7}```

### Symmetric Set Difference

The symmetric difference between Set A and B is the set of all the elements that are not common between the two sets. In other words, it is the set of all the elements of a union excluding the intersection elements.

To find out the set difference, you can either use the `^` operator or the `symmetric_difference()` method on a given set. The code given below illustrates the usage of this operator and method.

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

#Symmetric Difference of Set A and Set B
#Using ^ Operator
symm_diff = A ^ B

print(symm_diff)

#Symmetric Difference of Set A and Set B
#Using symmetric_difference() method
symm_diff = A.symmetric_difference(B)

print(symm_diff)```

Output.

```{1, 2, 3, 7, 8, 9}
{1, 2, 3, 7, 8, 9}```

## Python Set Methods

The different methods that can be applied to Python Set Objects are given below and described briefly.

### `add()`

Adds a new item into the set.

### `clear()`

It removes all of the items from the set and makes the set empty.

### `copy()`

It creates a new copy of the set.

### `difference()`

Returns the difference between two or more sets.

### `difference_update()`

It removes all elements of another set from the given set.

### `discard()`

It removes a particular item from a given set and if the item does not found in the set, it does nothing. (Does not raise any Exception)

### `intersection()`

It returns a new set containing the intersection of two sets.

### `intersection_update()`

This method updates the given set after the intersection of itself with another set.

### `isdisjoint()`

It returns `True` if two sets have nothing in common i.e. if the intersection of two sets is `Null`.

### `issubset()`

It returns `True` if a given set is a subset of another set.

### `issuperset()`

It returns `True` if a given set is a superset of another set.

### `pop()`

It removes and returns an arbitrary item from a given set and if the item does not found in this set, it raises `KeyError`.

### `remove()`

It removes a particular item from a given set and raises `KeyError` if the item does not found in the set.

### `symmetric_difference()`

It returns a new set that contains the symmetric difference between the two sets.

### `symmetric_difference_update()`

It updates the given set by doing its symmetric difference with itself and another set.

### `union()`

It returns a new set which is the union of the given set and another set passed as the argument.

### `update()`

It updates the set after doing a union of itself with another set.

## Built-in Functions that work with Python Sets

The following built-in functions can be used to perform different sorts of operations on Python Sets.

### `all()`

It returns `True` if all of the items of a given set are True. Also returns `True` if the set is empty.

### `any()`

It returns `True` if at least one of the items in a given set is True. This returns False if a set is empty.

### `enumerate()`

It returns an enumerate object for the given set. This is an object that contains the set items as key, value pair items.

### `len()`

It returns the length of a given set i.e. the number of items contained in the set.

### `max()`

It returns the largest item present in a given set.

### `min()`

It returns the smallest item present in a given set.

### `sorted()`

It returns a new list that contains the set elements in sorted order.

### `sum()`

It returns the sum of all of the set items.

## Python Frozenset

Frozenset is also a type of Set. But as its name suggests it is a set that is frozen. In other words, the elements or items of a frozenset can not be changed once defined i.e. no items can be added or removed from a frozenset. Therefore frozensets are immutable in nature. Python Lists are mutable, tuples are the immutable version of lists. Similarly, sets are mutable while the frozensets are the immutable version of the sets.

Sets are mutable and also unhashable. Python objects that are mutable and hashable can not be used as dictionary keys. But frozensets are immutable and hashable, therefore, they can be used as Dictionary keys. To create a frozenset, you just have to use the built-in function `frozenset()`. You can pass a set or any other collection object to this function and it will create a frozenset for the items contained in that particular object.

The following set methods can also be applied to a frozenset.

• `copy()`
• `difference()`
• `intersection()`
• `isdisjoint()`
• `issubset()`
• `issuperset()`
• `symmetric_difference()`
• `union()`

In the following python code, we’re creating frozensets from a set, dictionary, list, and tuple.

```a_list = [1, 2, 3, 4, 5, 5, 6]
a_tuple = (1, 2, 3, 4, 4, 5, 6)
a_dict = {
0 : 'A',
1 : 'B',
2 : 'C',
3 : 'D',
4 : 'E'
}
a_set = {1, 2, 3, 4, 5}

frozenset1 = frozenset(a_list)
frozenset2 = frozenset(a_tuple)
frozenset3 = frozenset(a_dict)
frozenset4 = frozenset(a_set)

print(frozenset1, type(frozenset1))
print(frozenset2, type(frozenset2))
print(frozenset3, type(frozenset3))
print(frozenset4, type(frozenset4))```

Output.

```frozenset({1, 2, 3, 4, 5, 6}) <class 'frozenset'>
frozenset({1, 2, 3, 4, 5, 6}) <class 'frozenset'>
frozenset({0, 1, 2, 3, 4}) <class 'frozenset'>
frozenset({1, 2, 3, 4, 5}) <class 'frozenset'>```

In the code snippet given below, we’ve applied some of the set methods on a frozenset.

```A = frozenset([1, 2, 3, 4, 5])
B = frozenset([3, 5, 6, 7, 8])

print(A.difference(B))

print(A.union(B))

print(A.intersection(B))

print(A ^ B)

As you can see in the output, the first four applied methods worked well but the `add()` method raises the `AttributeError` as the method `add()` is not applicable for a frozenset because it is immutable.
```frozenset({1, 2, 4})