## About

Implementation of a set data structure in Python.

- Sets are mutable. There is a non-mutable version of set called frozenset.
- The elements of a set are
**not**mutable. A set then cannot contain a list since lists are mutable. - A set cannot have a set as element.
- A set doesn't allow duplicates
- The number elements of a set are ordered

## Articles Related

## Initialization

You can use curly braces to give an expression whose value is a set.

```
>>> {1+2,3,'a'}
{3, 'a'}
```

The empty set is represented by set() and not by {} (which is a dictionary)

```
>>> x={}
>>> type(x)
<class 'dict'>
```

The duplicates are eliminated

Python prints sets using curly braces.

```
>>> {4,5,3}
{3, 4, 5}
```

The order in which the elements of the output are printed does not necessarily match the order of the input elements.

### Constructor

- With range

```
>>> set(range(10))
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
```

```
>>> set([1,2,3])
{1, 2, 3}
>>> set((1,2,3))
{1, 2, 3}
```

## Function

### Length

The cardinality of a set S is the number of elements in the set.

In Python, the cardinality of a set is obtained using the procedure len().

```
>>> len({3,4,5})
3
```

### Sum

- Sum beginning at 0

```
>>> sum({3,4,5})
12
```

* Sum beginning at 10

```
>>> sum({3,4,5},10)
22
```

## Comparator

### In

```
>>> S={1,2,3}
>>> 1 in S
True
>>> 1 not in S
False
```

### Equality

```
>>> S1={1,2,3}
>>> S2={1,2,3}
>>> S1==S2
True
```

## Operation

### union

```
>>> {1,2,3} | {4,5,6}
{1, 2, 3, 4, 5, 6}
```

### intersection

```
>>> {1,2,3} & {3,4,5}
{3}
```

## Mutation

### Add

```
>>> S={1,2,3}
>>> S.add(4)
>>> S
{1, 2, 3, 4}
```

The add method must not be used in a sub expression but apart

### Remove

```
>>> S={1,2,3}
>>> S.remove(2)
>>> S
{1, 3}
```

### Update

Add to a set all the elements of another collection (e.g. a set or a list)

```
>>> S
{1, 3}
>>> S.update({2})
>>> S
{1, 2, 3}
```

### Intersection Update

Intersect a set with another collection, removing from the set all elements not in the other collection.

```
>>> S
{1, 2, 3}
>>> S.intersection_update({1,2,5,7})
>>> S
{1, 2}
```

### Copy

```
>>> S
{1, 2}
>>> S2= S.copy()
>>> S2
{1, 2}
>>> S2.add(3)
>>> S2
{1, 2, 3}
>>> S
{1, 2}
```

```
>>> S
{1, 2}
>>> S2=S
# After executing the assignment statement S2=S, both S2 and S point
# to the same data structure (same address in memory)
>>> S2.remove(2)
>>> S
{1}
```

## Comprehension

### Introduction

Python provides expressions called comprehensions that let you build collections out of other collections.

They are useful in constructing an expression whose value is a collection, and they mimic traditional mathematical notation.

```
>>> {2*x for x in {1,2,3} }
{2, 4, 6}
```

It's a set comprehension over the set {1,2,3}. It is called a set comprehension because its value is a set.

The notation is similar to the traditional mathematical notation for expressing sets in terms of other sets, in this case:

<math>\{2x : x \in \{1, 2, 3\}\}</math>

### With an union or intersection

You can sue the union operator | or the intersection operator & in a comprehension:

```
>>> {x*x for x in {1,2} | {3, 4}}
{16, 1, 4, 9}
```

### With filtering

By adding a if condition (a filtering condition), you can skip some of the values in the set being iterated over:

```
>>> {str(x)+' is greater than 2' for x in {1, 2, 3, 4} if x>2}
{'4 is greater than 2', '3 is greater than 2'}
```

### Double comprehension

You can write a comprehension that iterates over the Cartesian product of two sets.

Example:

- The set of the products of every combination of x and y.

```
>>> {x*y for x in {1,2} for y in {1,2,3}}
{1, 2, 3, 4, 6}
```

- A double comprehension with a filter:

```
>>> {x*y for x in {1,2,3} for y in {2,3,4} if x != y}
{2, 3, 4, 6, 8, 12}
```