Borislav Hadzhiev
Wed Apr 20 2022·2 min read
Photo by Raychan
The Python "NameError: name 'reduce' is not defined" occurs when we use the
reduce()
function without importing it first. To solve the error, import the
function from the functools
module before using it -
from functools import reduce
.
Here is an example of how the error occurs.
def do_math(accumulator, current): return accumulator + current # ⛔️ NameError: name 'reduce' is not defined print(reduce(do_math, [1, 2, 3], 0)) # 👉️ 6
To solve the error, we have to import the reduce
function from the functools
module.
from functools import reduce def do_math(accumulator, current): return accumulator + current print(reduce(do_math, [1, 2, 3], 0)) # 👉️ 6
The reduce function takes the following 3 parameters:
Name | Description |
---|---|
function | A function that takes 2 parameters - the accumulated value and a value from the iterable. |
iterable | Each element in the iterable will get passed as an argument to the function. |
initializer | An optional initializer value that is placed before the items of the iterable in the calculation. |
You will often see the reduce()
function getting passed a lambda
:
from functools import reduce # 👇️ 6 print( reduce( lambda accumulator, current: accumulator + current, [1, 2, 3], 0 ) )
The lambda
function in the example takes the accumulated value and the current
value as parameters and returns the sum of the two.
If we provide a value for the initializer
argument, it is placed before the
items of the iterable in the calculation.
from functools import reduce def do_math(accumulator, current): print(accumulator) # 👉️ is 0 on first iteration return accumulator + current # 👇️ 6 print( reduce( do_math, [1, 2, 3], 0 # 👈️ initializer set to 0 ) )
In the example, we passed 0
for the initializer argument, so the value of the
accumulator
will be 0
on the first iteration.
The value of the accumulator
would get set to the first element in the
iterable if we didn't pass a value for the initializer
.
def do_math(accumulator, current): print(accumulator) # 👉️ is 1 on first iteration return accumulator + current # 👇️ 6 print( reduce( do_math, [1, 2, 3], ) )
If the iterable
is empty and the initializer
is provided, the initializer
is returned.
from functools import reduce def do_math(accumulator, current): return accumulator + current # 👇️ 100 print( reduce( do_math, [], 100 # 👈️ initializer set to 100 ) )
If the initializer
is not provided and the iterable contains only 1
item,
the first item is returned.
from functools import reduce def do_math(accumulator, current): return accumulator + current # 👇️ 123 print( reduce( do_math, [123], ) )
The list in the example only contains a single element and we didn't provide a
value for the initializer
, so the reduce()
function returned the list
element.