# Learn Python With Us - Sets

## An unordered, unindexed, mutable with immutable datatypes.

### Table of contents

- Important Links
- Youtube
- What is a set?
- Why Set is unordered?
- Declaration
- Data Types
- Set with basic built-in functions
- Accessing Elements of Set
- Adding elements to the set
- Removing Items from the Set
- Sorting
- Copying
- 1. Union
- 2. Intersection
- 3. Difference
- 4. Symmetric Difference
- 5. Disjoint
- 6. subset and superset.
- Exercise
- Challenges

### Important Links

**Series Link**: makereading.com/series/python

**Challenges: ** hackerrank.com/contests/makereading/challen..

### Youtube

### What is a set?

A set is a collection that is `unordered`

, `mutable with immutable data types`

, and `unindexed`

. Since it doesn't maintain the order, we can't use the index.

### Why **Set** is unordered?

So basically a set uses a **hashtable** as its underlying data structure. This explains the **O(1)** membership checking, since looking up an item in a **hashtable is an O(1)** operation, on average. Since the hashtable stores the key-value pair, it doesn't have a need to maintain the order or order of insertion. Now you know the reason for the unordered nature of the set.

### Declaration

A set data structure can be defined in two different methods,

**{}**using curly brackets.**set()**method.

#### 1. Using curly brackets

You can declare the set like below,

```
data = {'d1', 'd2', 'd3'}
print(data)
```

But there is one thing to be noted, (i.e) if you want to declare an empty set we can't use this curly brackets {}.

Let's see why,

```
data = {'d1', 'd2'}
print(type(data))
```

But If we are going to declare an empty set, probably we should not use curly bracket,

```
data = {}
print(type(data))
```

#### 2. Using **set()**

Using set() constructor, we can convert a list, tuple, set to a set.

**List to Set :**

```
data = set([1, 2, 3, 4])
print(data)
```

**Dictionary to Set**

```
data = set({1:1, 2:2, 3:3})
print(data)
```

**Tuple to Set**

```
data = set((1, 2, 3))
print(data)
```

### Data Types

Set is a **mutable** with the **immutable** data types. (i.e,) Set can comprise only strings, boolean, numbers, set, and tuple. It won't take a list, or dictionary as an element inside the set.

We already saw set is **internally built on top of the Hash Table**, and we can't generate a hash value for mutable data structures.

Let's see,

```
data = [1, 2, 3]
hash(data)
```

It will result in an error.

### Set with basic built-in functions

#### Length - len()

To find the length of the set,

```
data = {'a', 'b', 'c'}
print(len(data))
```

#### Type of data structure - type()

```
data = {'a', 'b', 'c'}
print(type(data))
```

**max() & min()**

To find the maximum value and the minimum value of a set,

```
values = {1, 2, 3, 4, 5, 6}
print("Max of values is ", max(values))
print("Min of values is ", min(values))
```

**any()**

If any of the values in the set is true (i.e,) Non-Zero , Non-Empty String, False values then it will return True, else False.

```
data = {0, 'makereading', False}
print(any(data)) # Will return True since it has 'makereading' non empty string.
data = {0, '', False}
print(any(data)) # Will return False since all the values are false.
```

**all()**

The all() function returns True if all items in an iterable are true, otherwise it returns False. If the iterable object is empty, the all() function also returns True.

```
data = {1, 2, 3}
print(all(data)) # True, since all the elements are having true value
data = {1, 2, 0}
print(all(data)) # False, since it has 0
```

### Accessing Elements of Set

Since the set is unordered, we can't access using the index values,

So the ways to access the set are,

**for**loop**in**and**not in**

#### 1. **for** loop

```
fruits = {"apple", "papaya", "banana", "orange"}
for element in fruits:
print(element)
```

**output: **

#### 2. **in and not in**

```
fruits = {"apple", "papaya", "banana", "orange"}
print("apple" in fruits)
print("orange" not in fruits)
```

**output: **

### Adding elements to the set

There are two ways of adding element to the set.

add() - Method to add an element to the set. It takes the immutable item as a parameter to add to the set.

update() - Method to merge an existing set with the mutable and immutable data structures.

**add()**

The add() method adds an element to the set. If the *element already exists*, the add() method **does not add** the element.

```
data = {1, 2, 3, 4, 5}
data.add(10)
print('data', data)
```

**update()**

Update() method takes only a single argument. The single argument can be a set, list, tuples or a dictionary. It automatically converts into a set and adds to the set.

**With Lists**

```
data = {1, 2, 3, 4, 5}
data.update([11, 10, 12])
```

**With Dictionary**

```
data = {1, 2, 3, 4, 5}
data.update({"a":"a", "b":"b", "c":"c"})
print(data)
```

**With String**

```
data = {1, 2, 3, 4, 5}
data.update('makereading')
print(data)
```

### Removing Items from the Set

We have many methods to delete, remove the items from the set,

remove()

discard()

pop()

del

clear

#### 1. Remove

If the element is present then it will remove, else it will throw error.

**Example 1: **

```
data = {1, 'python', 'set', 100}
data.remove('set')
print(data)
```

**Example 2:**

```
data = {1, 'python', 'set', 100}
data.remove('kuku')
print(data)
```

#### 2. discard()

**discard()** method is having the same functionality as the **remove()** method, but it will fail safe. (i.e) Even if the value is not there it wont throw an error.

**Example 1: **

```
data = {1, 'python', 'set', 100}
data.discard('set')
print(data)
```

**Example 2:**

Even if the element 'kuku' is not present, it wont throw an error.

```
data = {1, 'python', 'set', 100}
data.discard('kuku')
print(data)
```

#### 3. pop()

**pop()** method in set will remove any random element in the set and returns the removed element. Set is unordered, we can specify the index value as list.pop()

```
fruits = {'apple', 'orange', 'banana'}
removed_element = fruits.pop()
print(removed_element, fruits)
```

#### 4. del

**del** will delete the object itself.

```
fruits = {'apple', 'orange', 'banana'}
del fruits
print(fruits)
```

#### 5. Clear

Clear will empty the set,

```
fruits = {'apple', 'orange', 'banana'}
fruits.clear()
print(fruits)
```

### Sorting

We can sort the set, using `sorted`

function, but the return type of the sorted is `list`

.

```
fruits = {"apple", "orange", "lemon", "banana", "papaya"}
print(sorted(fruits))
```

### Copying

We can copy the set using the .copy() method,

```
fruits = {"apple", "orange", "lemon", "banana", "papaya"}
fruits_2 = fruits.copy()
fruits.add('pineapple')
print(fruits, fruits_2, id(fruits), id(fruits_2)
```

#### Mathematical Functionalities

Sets are the fundamental **property of mathematics**. Now as a word of warning, sets, by themselves, seem pretty pointless. But it's only when we apply sets in different situations do they become the powerful building block of mathematics that they are.

Math can get amazingly complicated quite fast. Graph Theory, Abstract Algebra, Real Analysis, Complex Analysis, Linear Algebra, Number Theory, and the list goes on. But there is one thing that all of these share in common: **Sets**.

During our school days, we might have learned about union, intersection, difference, venn diagrams and more.

Using the python sets, we can achieve the above functionalities,

### 1. Union

Union of two sets will return all the items present in both sets (all items will be present only once). This can be done with either the `|`

operator or the `union()`

method.

📝

`union()`

will return a new set. It's notinplacechange.

```
set_a = {"apple", "banana", "orange"}
set_b = {"lemon", "jackfruit", "strawberry"}
union_val = set_a.union(set_b)
print(union_val)
```

### 2. Intersection

The intersection of two sets will return only the common elements in both sets. The intersection can be done using the `&`

operator and `intersection()`

method.

```
fruits = {"apple", "orange", "banana" }
fav_fruits = {"apple", "jackfruit", "lemon"}
common_fruits = fruits & fav_fruits
print(common_fruits)
common_fruits = fruits.intersection(fav_fruits)
print(common_fruits)
```

`intersection()`

will return a new set. It's notinplacechange.

To have an inplace change, python provides `intersection_update`

functionality, to update the first set.

```
fruits = {"apple", "orange", "banana" }
fav_fruits = {"apple", "jackfruit", "lemon"}
fruits.intersection_update(fav_fruits)
print(fruits)
```

### 3. Difference

The difference operation will return the items that are present only in the first set i.e the set on which the method is called. This can be done with the help of the `-`

operator or the `difference()`

method.

```
fruits = {"apple", "orange", "banana" }
fav_fruits = {"apple", "jackfruit", "lemon"}
result = fruits.difference(fav_fruits)
print(result)
```

`difference()`

will return a new set. It's notinplacechange.

To have an inplace change, python provides `difference_update`

functionality, to update the first set.

```
fruits = {"apple", "orange", "banana" }
fav_fruits = {"apple", "jackfruit", "lemon"}
fruits.difference_update(fav_fruits)
print(fruits)
```

### 4. Symmetric Difference

The Symmetric difference operation returns the elements that are unique in both sets. This is the opposite of the intersection. This is performed using the ^ operator or by using the symmetric_difference() method.

```
fruits = {"apple", "orange", "banana" }
fav_fruits = {"apple", "jackfruit", "lemon"}
result = fruits.symmetric_difference(fav_fruits)
print(result)
```

`symmetric_difference()`

will return a new set. It's notin placechange.

To have an in-place change, python provides `symmetric_difference_update`

functionality, to update the first set.

```
fruits = {"apple", "orange", "banana" }
fav_fruits = {"apple", "jackfruit", "lemon"}
fruits.symmetric_difference_update(fav_fruits)
print(fruits)
```

### 5. Disjoint

Two sets are called disjoint sets if they don't have any element in common, the intersection of sets is a null set.

```
set_a = {1, 2, 3}
set_b = {4, 5, 6}
print(set_a.isdisjoint(set_b))
```

### 6. subset and superset.

The issuperset() method returns True if a set has every elements of another set (passed as an argument). If not, it returns False. Set X is said to be the superset of set Y if all elements of Y are in X . Here, set B is a superset of set A and A is a subset of set B .

```
set_a = {1, 2, 3, 4, 5}
set_b = {2, 4, 5}
print(set_a.issuperset(set_b), set_b.issubset(set_a))
```

### Exercise

**1: **Add a list of elements to a set, **clue: ** Use a constructor.

**2: **Return a new set of identical items from two sets, **clue: ** Use intersection.

**3: **Get Only unique items from two sets, **clue: ** Use union.

**4: **Update the first set with items that don’t exist in the second set, **clue: ** difference; in place

**5: **Remove items from the set at once, **clue: ** remove, pop, clear

**6: **Return a set of elements present in Set A or B, but not both, **clue: ** symmetric difference

**7: **Check if two sets have any elements in common. If yes, display the common elements, **clue: ** intersection

**8: **Update set1 by adding items from set2, except common items, **clue: ** difference

**9: **Remove items from set1 that are not common to both set1 and set2, **clue: ** intersection update

### Challenges

**Hackerrank**- hackerrank.com/contests/makereading/challen..

### Did you find this article valuable?

Support **Make Reading** by becoming a sponsor. Any amount is appreciated!