#Day13 - Map, Filter, Sorted, and Reduce in Python
Tags: 100daysofcode, python, programming, codenewbie
Published: 2021-04-03 01:30:54

In this article, we will be discussing the following functions in Python
- map
- filter
- sorted
- reduce

In yesterday's article (Day 12), we discussed Lambda Functions in Python. Lambda functions can be used with the above-mentioned functions. 

We will be using the following list 
```
import random
pairs = [(random.randint(0,10),random.randint(0,10)) 
              for _ in range(5)]
```

It is basically a list of pairs of random integers

### Map()
The map function takes in an iterable (list, tuple, etc) and a function as parameters. It calls the function on each element in the iterable.
```
map(function,iterable)
```
Consider the following code snippet
```
def map_func(elem):
    return elem[0]*elem[1]

mapped_lst = map(map_func, pairs)
```

The function **map_func** takes in a tuple as a parameter and returns the product of the first two elements. Now, if we want to use the **map_func** on each element in our previously defined list **lst**, we would pass **lst** as the iterable and **map_func** as the function to the **map** function.

Notice, we are only passing the function's name. Each element in the list **lst** is passed as the parameter

map returns a map object which is also iterable. We could either use a for loop to iterate over the returned object or just convert it to a list using **list()**
```
print(list(mapped_lst))
```
```
Input: [(1, 8), (3, 9), (10, 10), (9, 4), (4, 7)]
Output: [8, 27, 100, 36, 28]
```

#### Using map with lambda functions
Instead of defining a function **map_func**, we could just use an anonymous/lambda function. You can check out my article on Day 12 to learn more about lambda functions

```
mapped_lst = map(lambda elem: elem[0]*elem[1], pairs)
```
Combining map() with lambda functions makes it look cleaner.

### Filter()
The **filter()** function essentially filters elements in a list. A function returning a boolean value along with an iterable are passed as parameters to the **filter()** function. Like the **map()** function, the **filter()** function also executes on all the elements in an iterable. It only returns the element if the function passed as a parameter returns True. If this is confusing, take a look at the example below

```
def filter_func(elem):
    max_elem = max(elem[0] , elem[1])
    return max_elem > 7

filter_lst = filter(filter_func, pairs)
```
The **filter_func()** returns true if the maximum element in the tuple is greater than 7.  This function is executed on all the elements of the list **lst**. Only the elements with a number greater than 7 return True and are returned. The **filter()** function returns a filter object. Similar to the map object, the filter object is also iterable and can be converted to a list.

```
print(list(filter_lst))
```
```
Input: [(7, 10), (0, 0), (9, 2), (4, 5), (2, 8)]
Output: [(7, 10), (9, 2), (2, 8)]
```
#### Filter with lambda functions
```
filter_lst = filter(lambda elem: elem[0]*elem[1] > 7, pairs)
```

### Sorted()
The **Sorted()** is pretty self-explanatory, it is used to sort an iterable. It can directly be used on a list of numbers or strings.
```
strings = ["aa" , "cc" , "bb"]
sorted_lst = sorted(strings)
rev_sorted_lst = sorted(strings, reverse = True)
```
You can set the **reverse** parameter to True if you want to sort it in descending order
```
Input: ['aa', 'cc', 'bb']
Output: ['aa', 'bb', 'cc']
Output: ['cc', 'bb', 'aa']
```
#### Sorted with custom key
What if we want to sort our list of pairs? 

We can specify the function on which we want to sort our iterable. Let's say we want to sort based on the product of both the numbers in the tuple.

```
def key_func(elem):
    return elem[0]*elem[1]

sorted_pairs = sorted(pairs, key = key_func)
rev_sorted_pairs = sorted(pairs, key = key_func,reverse = True)
```
**key_func()** returns the product of the two numbers in the pair. The **key** parameter in the **sorted** function is set to the our **key_func**. Based on the integer returned by the **key_func**, the list is sorted. The function we use to sort has to return an integer.

```
Input: [(1, 6), (3, 0), (5, 7), (6, 10), (4, 7)]
Output: [(3, 0), (1, 6), (4, 7), (5, 7), (6, 10)]
Output: [(6, 10), (5, 7), (4, 7), (1, 6), (3, 0)]
```
#### Sorted with lambda function
Let's say we have a list of strings and we want to sort it in ascending order based on the length of the string.
```
lst = ['a' , 'aba' , 'asd' , 'sdsds' , 'asdasdasfasf', 'asasa']
sorted_lst = sorted(lst, key = lambda elem: len(elem))
rev_sorted_lst = sorted(lst, key = lambda elem: len(elem),reverse = True)
```
We create a lambda function that basically returns the length of the string, this is used to sort the list.
```
Input: ['a', 'aba', 'asd', 'sdsds', 'asdasdasfasf', 'asasa']
Output: ['a', 'aba', 'asd', 'sdsds', 'asasa', 'asdasdasfasf']
Output: ['asdasdasfasf', 'sdsds', 'asasa', 'aba', 'asd', 'a']
```

### Reduce()
The **reduce** functions works in the following way:
- The function passed is called on the first two elements and a value is returned
- The function is called on the value returned last time and the third element
- The function is called on the value returned previously and the fourth element
- and so on

In the final function call, the value is returned. Unlike **map()*, **filter()** and **sorted()**, **reduce()** returns a single value and not an iterable.

If it is confusing, look at the example below
```
from functools import reduce
lst = [7,10,2,6,1,5]

def reduced_func(x,y):
    return x +y 
    
reduced_value = reduce(reduced_func,lst)
```
**reduced_func** returns the sum of two numbers. To use the **reduce()** function, we need to import it from the **functools** library. 

- First **reduced_func (7,10)** is called. This returns 17
- Then **reduced_func(17,2) is called. This returns 19
- Then **reduced_func(19,6) is called.

After the first function call, the function is called on the value returned in the previous function call and the next element in the list.

```
Input: [7, 10, 2, 6, 1, 5]
Output: 31
```
Finally, the last function call's value is returned.


#### Reduce() function with lambda
```
reduced_value = reduce(lambda x,y: x+y,last)
```