# Sets in python a tutorial

In this tutorial , we will show how to use sets in python . We will start by explaining what is a set. After that we will explain how to use sets , so the various operations that we can perform , finally we will give some practical usage examples of a set . I will also provide a summary for the various operations that can be performed on a set .

## what is a set

A set in python is a sequence of unique unordered elements. hence it doesn’t contain any duplicate . We can perform mathematical operations on a set , such as membership testing , intersection union … This being said , we can use sets to remove duplicate from an iterable.

Sets are not subscriptable , hence we cannot access a set using the index operator [] , and we cannot perform slicing , or any operation that is dependent on being able to be indexed .

Sets are mutable , we can add and remove elements from a set , but a set cannot contain mutable elements such as a sequence or a dictionary , or a set.

## Creating a set

We can create a set by using the `set(iterable)` notation or by using the literal `{element,}` notation . The `{}` cannot be used to create an empty set , as this used to create a dictionary.

```>>> _set = set(['pen', 'pen', 'notebook'])
# create a set from an iterable

>>> print(f'_set : {_set}')
{'notebook', 'pen'}
all duplicate are removed

>>> _dict = {}
# {} is used to create an empty dictionary not an empty set

>>> print(type(_dict))
# <class 'dict'>

>>> _set = {1,2,3,1,2,3}
# create a set using {element ,}

>>> print(f'_set : {_set}')
_set : {1, 2, 3}
```

## Adding elements to a set

we cannot alter an element in a set , since we cannot use the subscript operator , and there are no methods to change a specific element . We can add or remove elements to a set . To add elements , we use the set add method as follows :

```>>> _set = {'cup', 'pen', 'ipad'}
# create a set

>>> _set

>>> _set

>>> _set
```

## Remove elements from a set

• we can remove an arbitrary element from a set using set.pop. set.pop will throw keyError if the set is empty , if it is not empty it will remove an return the element
• we can remove a specific element from a set using set.discard
• we can clear all the set elements using set.clear() method
```>>> _set = set('removing elements from a set an example')
>>> _set
{'t', 'x', 'a', 'n', 'f', 'v', 'm', 'e', 'i', 'l', 'p', 'g', ' ', 's', 'r', 'o'}

# popping an arbitrary element from a set
>>> _set.pop()
'n'
>>> _set.pop()
'g'

#removing a specific element
# if the element doesn't exist discard does nothing

#clear all elements of a set
>>> _set.clear()
>>> _set
set()
```

## Basic set operations

we can perform some basic set operations . they are the union , the intersection , the difference , the symmetric difference (union – intersection )

```>>> _setOne = {1, 2, 3, 4, 5}
>>> _setTwo = {4, 5, 6, 7, 8, 9}

# union
>>> _union = _setOne | _setTwo
>>> _union
{1, 2, 3, 4, 5, 6, 7, 8, 9}

>>> _union = _setOne.union(_setTwo)
>>> _union
{1, 2, 3, 4, 5, 6, 7, 8, 9}

# intersection
>>> _intersection = _setOne & _setTwo
>>> _intersection
{4, 5}

>>> _intersection = _setOne.intersection(_setTwo)
>>> _intersection
{4, 5}

# subtraction
>>> _subtraction = _setOne - _setTwo
>>> _subtraction
{1, 2, 3}

>>> _subtraction = _setOne.difference(_setTwo)
>>> _subtraction
{1, 2, 3}

# symmetric difference union - intersection
>>> _symmetricDifference = _setOne ^ _setTwo
>>> _symmetricDifference
{1, 2, 3, 6, 7, 8, 9}

>>> _symmetricDifference = _setOne.symmetric_difference(_setTwo)
>>> _symmetricDifference
{1, 2, 3, 6, 7, 8, 9}
```

## Sets Relationship

we can check if one set is a subset or superset of another . we can also check if two sets are disjoint hence they have no elements in common .

```_setOne = {1, 2, 3, 4, 5}
_setTwo = {1, 2, 3, 4, 5, 6}

# check if a set is a subset of another
>>> _setOne.issubset(_setTwo)
True

>>> _setOne < _setTwo
True

>>> _setOne.issubset(_setOne)
True

>>> set().issubset(_setOne)
True

>>> set().issubset(set())
True

# check if a set is a superset of another
>>> _setTwo.issuperset(_setOne)
True

>>> _setTwo > _setOne
True

>>> _setTwo.issuperset(_setTwo)
True

>>> set().issuperset(_setOne)
False

>>> set().issuperset(set())
True

# check if two sets are disjoint
>>> _setOne.isdisjoint(_setTwo)
False

>>> {''}.isdisjoint(_setTwo)
True

#check if two sets are equal
>>> _setOne == _setTwo
False

#check if two sets don't have the same elements
>>> _setOne != _setTwo
True
```

## Updating a set

we can update a set , so update the elements inside a set using :

• update (union update): calculate the union of set a and set b , and set the result to a
• intersection_update : calculate the intersection of a and b and set the result to a
• difference_update : remove the elements of set b from set a and set the result to a
• symmetric_difference_update : calculate the union minus the intersection of set a and b and set the result to a
```>>> _setOne = {'a', 'b'}
>>> _setTwo = {'b', 'c', 'd'}

# update
>>> _setOne |= _setTwo
>>> _setOne
{'b', 'd', 'a', 'c'}

>>> _setOne = {'a', 'b'}
>>> _setOne.update(_setTwo)
>>> _setOne
{'b', 'd', 'a', 'c'}

# intersection update
>>> _setOne = {'a', 'b'}
>>> _setOne &= _setTwo
>>> _setOne
{'b'}

>>> _setOne = {'a', 'b'}
>>> _setOne.intersection_update(_setTwo)
>>> _setOne
{'b'}

# difference update
>>> _setOne = {'a', 'b'}
>>> _setOne -= _setTwo
>>> _setOne
{'a'}

>>> _setOne = {'a', 'b'}
>>> _setOne.difference_update(_setTwo)
>>> _setOne
{'a'}

# symmetric difference update
>>> _setOne = {'a', 'b'}
>>> _setOne ^= _setTwo
>>> _setOne
{'c', 'd', 'a'}

>>> _setOne = {'a', 'b'}
>>> _setOne.symmetric_difference_update(_setTwo)
>>> _setOne
{'c', 'd', 'a'}
```

## Testing if an element is in a set

we can use the in operator to test if an element is inside a set

```>>> _setOne = {1, 2, 3, 4}

>>> 1 in _setOne
True

>>> 'a' in _setOne
False
```

## Looping and list comprehension

```>>> _set = {'small cup', 'medium cup', 'large cup'}
>>> for _s in _set:
...     print(_s)
...
medium cup
small cup
large cup

>>> _setOnlySmall = {_s for _s in _set if _s == 'small cup'}
>>> _setOnlySmall
{'small cup'}
```

## Copying a set

```>>> _setOne = {1, 2, 3, 4}
>>> _setTwo = _setOne.copy()
>>> _setOne == _setTwo
True
>>> _setOne
{1, 2, 3, 4}
```

## Time Complexity

From python wiki ## Practical examples about using sets

### Purging data

Let us say we have some data , that we have gotten from a source , and that this data needs some purging .

For example we are doing the inventory , and we are not sure if the person who was doing the inventory made any error . As such we want to remove any duplicate data.

The data is in a file , and the names of the materials are separated by space . So we can represent this as having a string containing the name of the materials separated by a space .

```>>> data = 'cup coffee charger phone phone cup coffee charger'
>>> dataPurged = set(data.split(' '))

>>> data
'cup coffee charger phone phone cup coffee charger'

>>> dataPurged
{'cup', 'coffee', 'charger', 'phone'}.
```

### Checking if the letters of a string are contained within another one

Let us say we have an alphabet stored in a string , and we want to check if a word is formed from this alphabet , hence we can rephrase the problem into checking if the letters in this word are in the alphabet .

```>>> alphabet = 'abcdefghijklmnopqrstuvwxyz'
>>> word= 'wordverifyformedfromalphabet'
>>> set(word)< set(alphabet)
True
```

## Set operations quick summary

• creation
• _set = set(iterable)
• _set = {element , } # cannot use {} without any element inside
• removing elements
• _set.clear() #empty the set
• _set.pop() #remove an arbitrary element from a set , throw keyError if set empty
• _set.discard(element) # remove element from set , doesn’t return anything and doesn’t throw an error
• Basic set operations
• _union = _setOne | _setTwo
• _union = _setOne.union(_setTwo)
• _intersection = _setOne & _setTwo
• _intersection = _setOne.intersection(_setTwo)
• _symmetricDifference = _setOne ^ _setTwo # Union Minus Intersection
• _symmetricDifference = _setOne.symmetric_difference(_setTwo)
• Basic sets relationships
• _setOne.issubset(_setTwo)
• _setOne < setTwo # _setOne.issubset(_setTwo)
• _setTwo.issuperset(_setOne)
• _setOne > setTwo # _setTwo.issuperset(_setOne)
• _setOne.isdisjoint(_setTwo) # no elements in common
• _setOne == _setTwo # they have the same elements
• _setOne != _setTwo # they don’t have the same elements
• Updating a set
• _setOne |= _setTwo # union update
• _setOne.update(_setTwo) # union update
• _setOne &= _setTwo # intersect update
• _setOne.intersection_update(_setTwo) # intersect update
• _setOne -= _setTwo #difference update
• _setOne.difference_update(_setTwo) # difference update
• _setOne ^= _setTwo # symmetric difference update
• _setOne.symmetric_difference_update(_setTwo) # symmetric difference update
• Testing if an element is in a set
• elem in _setOne
• Looping and list comprehension
• for _s in _set : #do something #not in order
• {_s for _s in _set if _s is int} # not in order
• copying
• _setOne.copy() # creates a shallow copy