Python list reduce

Learn about Reduce Function in Python

The reduce() function in python performs functional computation by taking a function and an iterable (eg: list, tuple, dictionary etc.) as arguments and result is returned after computation (the process of applying the function on the iterable).

The reduce() function in python is defined in functools module and doesn't return multiple values or any iterator, it just returns a single value as output which is the result of whole iterable getting reduced to only single integer or string or boolean.

The reduce() function in python takes a pre-defined function and apply it to all the elements in an iterable (eg: list, tuple, dictionary etc.), and compute single valued result. This single valued output is a result of applying the reduce function on the iterable passed as an argument, only a single integer or string or boolean is returned.

reduce() is very handy for processing iterables without programming explicit For loops. This reduce() function is similar to a for loop in Python, reduce() is an in-built function function and is programmed in C language , which makes it much optimized and faster.

The reduce() function in python is a part of functools module which has to be imported before calling the function in our program. This single value output means that after applying the reduce function on the iterable only a single integer or string or boolean is returned.

functools.reduce(function, iterable)

  • The first argument in reduce() is a function. This function will be applied to all the elements in an iterable in a cumulative manner to compute result.
  • The second argument is an iterable. Iterables are those python objects that can be iterated/looped over, includes like lists, tuples, sets, dictionaries, generators, iterator etc.

The reduce() function in python is a part of functools module and doesn't return multiple values, it just returns a single value.

Steps of how reduce function works in python:

  • The function passed as an argument is applied to first two elements of the iterable.
  • After this, the function is applied to the previous generated result and to the next element in the iterable.
  • This process continues untill the whole iterable is processed.
  • The single value is returned as a result of applying the reduce function on the iterable.

In this example we have defined a lambda function that calculates the sum of two numbers on the passed list as an iterable using the reduce function.

from functools import reduce nums = [1, 2, 3, 4] ans = reduce(lambda x, y: x + y, nums) print(ans)

Output

The above python program returns the sum of whole list as a single value result which is calculated by applying the lambda function which solves the equation (((1+2)+3)+4)

Example using pre-defined function (Multiplying Numeric Values)

Now, a pre-defined function product which return the product of 2 numbers passed into it, is used as an argument in the reduce function which is passed along with a list of numbers.

from functools import reduce # calculates the product of two elements def product(x,y): return x*y ans = reduce(product, [2, 5, 3, 7]) print(ans)

Output

We get result as 24, because the steps followed by the reduce function calculates the result of the following equation(((2x5)x3)x7). That is, first the multiplication of 2 and 5 is done and result of this multiplication is further done with all the other elements of the list one-by-one.

Example using Operator Functions in python

Sometimes reduce function is implemented along with Operator functions in python. Operator functions are the basic pre-defined mathematical, logical and bitwise operations combined inside a single module in python named operator. Lets explore the explore the way of using reduce function with operator functions.

import functools # importing operator module import operator dummy = [-1, 5, 10, 6, 3] # using reduce to calculate sum of list along with add operator function print(f'The sum using add opertor functions is {functools.reduce(operator.add, dummy)}') # using concat oeprator function to join strings print(functools.reduce(operator.concat, ["Scaler ", "Academy"]))

Output

The sum using add opertor functions is 23 Scaler Academy

The above python program first calculates the sum of given list of numbers named dummy using function operator.add that calculates the sum of 2 numbers at a time which is then used to calculate for the whole list using reduce function. While in the second example 2 strings present in the list are concatenated together using the operator.concat function which is reduced into single string result using reduce function.

You must be wondering what will happen if an empty list is passed as an argument to the reduce function. Lets check it with the help of an example.

from functools import reduce ans = reduce(lambda a, b: a + b, []) print(ans)

Output

Traceback (most recent call last): File "C:\Users\NAMANJEET SINGH\Documents\Scratch.py", line 24, in <module> ans = reduce(lambda a, b: a + b, []) TypeError: reduce() of empty sequence with no initial value

So we a got a Type Error stating the fact that there is no initial value for an empty sequence. This basically means that in case of an empty list a third argument called as initializer has to be passed in the reduce function which will help us counter this error as now the initializer is placed before the items of the iterable while calculating the sum and it is used as default value in case the list is empty.

Reduce function in python can be used to calculate Minimum and Maximum value from the iterable by comparing items within the given iterable.The below program includes two different pre-defined functions.

The first function will take two arguments, a and b, and return their minimum., while the second function will use a similar process to return the maximum value

from functools import reduce # pre-defined function to calculate minimum def mini(a, b): return a if a < b else b # pre-defined function to calculate maximum def maxi(a, b): return a if a > b else b nums = [3, 5, 2, 4, 7, 1] # passing both functions in the reduce along with nums as iterable print(f'The minimum in the given list is {reduce(mini, nums)}') print(f'The maximum in the given list is {reduce(maxi, nums)}')

Output

The minimum in the given list is 1 The maximum in the given list is 7

The above program when executed first runs the reduce() with mini() and maxi(), to get the minimum and maximum value out of the provided two arguments. The reduce function then iterates over every element of the iterable, compares them in cumulative pairs, and finally returns the minimum or maximum value as the result.

Checking if All Values Are True

To check whether all values in the given iterable are True or not we can write a function that takes two arguments and returns True if both arguments are true. If one or both arguments are false, then the function will return False.

from functools import reduce # creating a function to check if both arguments are True or not def is_true(a, b): return bool(a and b) print(reduce(is_true, [1, 1, 1, 1, 1])) print(reduce(is_true, [1, 1, 1, 1, 0]))

Output

In the first example all elements in the iterable are 1 because of which reduce function returns True while in the second example only 1 element is 0 which makes the whole iterable return False as bool(a and b) is used and for this expression to be True both arguments have to be 1.

Checking if Any Value is True

To check whether any value in the given iterable is True or not we can write a function that takes two arguments and returns True if either one of the two arguments is true. If both arguments are false, then the function will return False.

from functools import reduce # creating a function to check if both arguments are True or not def is_true(a, b): return bool(a or b) print(reduce(is_true, [1, 1, 0, 1, 1])) print(reduce(is_true, [0, 0, 0, 0, 0]))

Output

In the first example all elements in the iterable are 1 except one because of which reduce function returns True while in the second example all elements are 0 which makes the whole iterable return False.

After learning about Reduce you might have got confused between reduce and map function. The main difference between these two is that map() is applied to every item of an iterable one at the time and in result an iterator is returned.

Lets see how is a map() function implemented

# using map function with lambda function on an iterable ans = map(lambda a: 2*a, [3, 5]) # to check what is the type of map() print(type(ans)) print(list(ans))

Output

In the above program the map function applies the lambda function to every element in the iterable one-by-one and at the end an iterator is returned. Here, the type of returned list is of <class 'map'>.

In the itertools module a function named accumulate() is present which takes an iterable as an argument and in some cases a function is also passed as an optional second argument.

Syntax : itertools.accumulate(iterable)

The accumulate function returns an iterator that consists of accumulated sums of every item in the iterable. So the working of accumulate varies from the reduce function where only a single value is the result.

from itertools import accumulate nums = [1, 2, 3, 4] # to check the return type of accumulate print(type(accumulate(nums))) # printing the iterator print(list(accumulate(nums)))

Output

<class 'itertools.accumulate'> [1, 3, 6, 10]

As we can see the return type is of <class 'itertools.accumulate'> and the iterator returned is a result of the accumulated sums expression [1, (1+2), (1+2+3), (1+2+3+4)].

A For loop can do the same thing which a reduce function does in python, so there is no difference in the functionality between these two, but when it comes to the amount of code to be written to implement the same thing, reduce function has a big advantage over traditional python for loop. Lets understand with an example.

from itertools import accumulate from functools import reduce nums = [1, 3, 5, 7] # using for loop to calculate sum of list ans = 0 for i in nums: ans += i print(ans) # single line code using reduce print(reduce(lambda x,y: x+y, nums))

The above program calculates the sum of all elements present in the nums array. Both for loop and reduce function produce same correct output and the only difference between the traditional loop and reduce function is that the latter method out performs the for loop when the size of the list is very large as it is very optimized and efficient.

Reduce function returns a single value as a result while a list comprehension when applied to a list return another list.

In some cases like flattening a list of lists into a single list we can use a list comprehension. Lets deep dive in this flattening of list with the hep of an example.

from functools import reduce # a 2D list matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # using reduce function for flattening a 2D list print(reduce(lambda x, y: x + y, matrix)) # using list comprehension print([i for row in matrix for i in row])

Output

[1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9]

In the above program a 2D list is flattened by using reduce function where the first 2 lists are combined and a new list is created which is further passed to reduce function along with the successive list.

While in case of list comprehension, iteration is done for every row in the matrix and every item in that particular row is returned.

As we have already covered a case where an empty list was passed as an argument to the reduce function, a new 3rd argument initializer is used.

To put it in a simple way reduce() places the 3rd parameter before the value of the second one, if it’s present. Thus, it means that if the 2nd argument is an empty sequence, then 3rd argument serves as the default one.

from functools import reduce tupl = (1, 4, 8, 18, 22) # using reduce with initializer = 3 print(reduce(lambda x, y: x+y, tupl, 3))

Output

The above program takes initializer = 3 as an argument in the reduce function, the lambda function calculates the sum of whole tuple but in this case the sum will be initialised by default value of 3 which is the value of initializer. Therefore the output will be sum of elements in tuple + 3 = 56

  • Reduce function in python allows us to perform reduction operation on iterables using python callables and lambda functions. reduce() applies a function to the items in an iterable and reduces them to a single cumulative value.
  • Python's reduce function performs various common problems like addition or multiplication of numbers in iterables.
  • Reduce function is a very popular method in functional programming even though it has been replaced by many pythonic functions like sum(), any(), min() etc.