Functional programming is a programming paradigm that breaks down a problem into individual functions. In this paradigm, we avoid mutable data types and state changes as much as possible. It also emphasizes RECURSION rather than loops. map(), filter() and reduce() are the three cornerstone functions of functional programming.
map()
This first argument to map() is a transformation function, where each original item is transformed into a new one.
num = [2, 3, 6, 9, 10]
def cube(num):
return num ** 3
cubed = map(cube, num)
print(list(cubed))
Another way:
cubed = map(lambda n: n ** 3, num)
Another method:
list(map(lambda x, y: x / y, [6, 3, 5], [2, 4, 6]))
[3.0, 0.75, 0.8333333333333334]
A lot of math-related transformations can be performed with map().
For tuples we use starmap().
import itertools
num = [(2, 3), (6, 9), (10,12)]
multiply = itertools.starmap(lambda x,y: x * y, num)
list(multiply) # [6, 54, 120]
filter()
A filtering operation processes an iterable and extracts the items that satisfy a given condition. The function argument must be a single-argument function. It’s typically a boolean-valued function that returns either True or False. The filter() accepts only one iterable.
num = [12, 37, 34, 26, 9, 250, 451, 3, 10]
even = list(filter(lambda x: (x % 2 == 0), num))
print(even)
sort()
The sort method is a helpful tool to manipulate lists in Python. For example, if you need to sort a list in ascending or reverse order, you can use the following:
num = [24, 4, 13, 35, 28]
num.sort()
num.sort(reverse=True)
It is important to note that the sort() method mutates the original list and it is therefore impossible to revert back the list’s items to their original position.
groupby()
ITERTOOLS.GROUPBY() takes a list of iterables and groups them based on a specified key. The key is useful to specify what action has to be taken to each individual iterable. The return value will be similar to a dictionary, as it is in the {key:value} form. Because of this, it is very important to sort the items with the same key as the one used for grouping.
import itertools
spendings = [("January", 25), ("February", 47), ("March", 38), ("March", 54), ("April", 67),
("January", 56), ("February", 32), ("May", 78), ("January", 54), ("April", 45)]
spendings_dic = {}
func = lambda x: x[0]
for key, group in groupby(sorted(spendings, key=func), func):
spendings_dic[key] = list(group)
print(spendings_dic)
{'April': [('April', 67), ('April', 45)],
'February': [('February', 47), ('February', 32)],
'January': [('January', 25), ('January', 56), ('January', 54)],
'March': [('March', 38), ('March', 54)],
'May': [('May', 78)]}
In the above snippet, we used sorted() instead of sort(). This is because we wanted to sort an iterable that was not a list.
Contrary to sort(), sorted() will create a copy of the original list, making it possible to retrieve the original order.
Finally, we can use map() from the previous section to sum the monthly expenses:
monthly_spendings = {key: sum(map(lambda x: x[1], value)) for key, value in spendings_dic.items()}
print(monthly_spendings)
{'April': 112, 'February': 79, 'January': 135, 'March': 92, 'May': 78}
reduce()
The REDUCE() function implements a technique called FOLDING or reduction. It takes an existing function, applies it cumulatively to all the items in iterable, and returns a single final value.
reduce() was originally a built-in function and was moved to functools.reduce() in Python 3.0.
Unless you cannot find any solution other than reduce(), you should avoid using it. The reduce() function can create some abysmal performance issues because it calls functions multiple times, making your code slow and inefficient. Functions such as sum(), any(), all(), min(), max(), len(), math.prod() are faster, more readable, and Pythonic.
from functools import reduce
yearly_spendings = reduce(lambda x, y:x + y, monthly_spendings.values())
print(yearly_spendings)
496