9
In which cases is useful and how can I use the function reduce
?
9
In which cases is useful and how can I use the function reduce
?
14
The function reduce
, available in the built-in module functools
, serves to "reduce" an iterable (as a list) to a single value.
It is a slightly more common paradigm in functional languages, but it is also quite useful in object-oriented/imperative languages like Python.
But as such, "narrows down" a list?
Suppose you have a list minha_lista
, that only contains numbers, and that you want the result of multiplication among all these numbers. One of the ways to do this is with a for:
# Queremos 2 * 4 * 5 * 2, que é igual a 80
minha_lista = [2, 4, 5, 2]
produto_total = 1
for numero in minha_lista:
produto_total *= numero
print(produto_total) # 80
This works, but can also be done with reduce
:
from functools import reduce
minha_lista = [2, 4, 5, 2]
def mult(x, y):
return x * y
produto_total = reduce(mult, minha_lista)
print(produto_total) # 80
Or, equivalently but a little more concisely, with a function lambda (which is nothing more than a function defined in a single expression/line):
from functools import reduce
minha_lista = [2, 4, 5, 2]
produto_total = reduce(lambda x, y: x * y, minha_lista)
print(produto_total) # 80
So what’s going on there? If we take a look at "slow motion," what happens is this:
reduce
receives as function argument applied to the function mult
(or lambda in the second case)reduce
receives as eternal the list minha_lista
reduce
consider how x
and y
, respectively, the first two elements of minha_lista
: 2 and 4reduce
applies to x
and y
the function mult
, which multiplies one by the other: in 2 * 4
, the result is 8.x
, and the next unprocessed element (5, third element of our list) becomes y
mult
is applied to x
and y
: 8 * 5
returns 40
, and this value returned becomes our new x
The function mult
is last applied to x
and the last item on our list, 2
. 40 * 2
returns us 80
As there are no more elements to apply the function, reduce
returns the final result: 80, as expected.
In short, the function applies another function sequentially and cumulatively to a list (iterator), and "reduces" the list to a single final result.
Another educational example is to calculate the minimum value of a list:
from functools import reduce
minha_lista = [2, 4, 5, 2, 1]
def achar_minimo(x, y):
if x < y:
return x
else:
return y
minimo = reduce(achar_minimo, minha_lista)
print(minimo) # 1
In this case, the first argument x
is used to hold the lowest value seen, and it is compared to other values y
of the list.
I say that this example is didactic because there is already an equivalent function in Python: a min
. Still, I think the example is nice to give another idea of the power of reduce
.
In addition to the above, the reduce
also accepts an optional third argument, the initial_value
. As the name implies, this argument can be given as initial value, and it is in effect the same thing as putting that value at the beginning of your list.
These examples are simple and may seem silly, but as the applied functions become more complex, use the reduce
can be a good one to decrease the size of the code and make it clearer. Anyway, it is a good tool to have.
Browser other questions tagged python python-3.x functional-programming
You are not signed in. Login or sign up in order to post.
I think it is important to add that the most common is to use "reduce" with a third parameter, representing the initial value for "x".
– jsbueno
@jsbueno good, I added a paragraph on that!
– Pedro von Hertwig Batista