"TypeError: <lambda>() takes 1 positional argument but 2 were given" using reduce()
Question:
I want to return sum of square of numbers passed in list.
from functools import reduce
def square_sum(numbers):
return reduce(lambda x: x ** 2, numbers)
print(square_sum([1, 2, 2]))
However i am getting the error: TypeError: <lambda>() takes 1 positional argument but 2 were given
.
I couldn’t understand reason behind it.
Answers:
Here’s how you might define sum
if it didn’t exist:
from functools import reduce
def sum(it):
return reduce(lambda acc, val: acc + val, it)
Or:
from functools import reduce
import operator
def sum(it):
return reduce(operator.add, it)
functools.reduce
reduces the values produced by an iterator to a single value by repeatedly combining consecutive values using the function you provide. So the function needs to be able to combine two values and therefore must take two arguments.
So you could define sum_of_squares
using reduce
, like this, although there are a lot of corner cases to cope with:
from functools import reduce
def sum_of_squares(it):
it = iter(it)
try:
first = next(it)
except StopIteration:
return 0
return reduce(lambda acc, val: acc + val * val,
it,
first * first)
Personally, I think the following is clearer:
def sum_of_squares(it):
return sum(map(lambda x: x ** 2, it))
The function
parameter to reduce()
should take two arguments: an old one and a new one. To sum, you’d just need to add them together:
lambda r, x: x**2 + r
However, that doesn’t get the right answer if the first element is >1. You might be thinking reduce()
is like sum(map())
:
def square_sum(numbers):
return sum(map(lambda x: x**2, numbers))
But it’s more readable to replace the map
with a generator expression:
def square_sum(numbers):
return sum(x**2 for x in numbers)
print(square_sum([1, 2, 2])) # -> 9
I want to return sum of square of numbers passed in list.
from functools import reduce
def square_sum(numbers):
return reduce(lambda x: x ** 2, numbers)
print(square_sum([1, 2, 2]))
However i am getting the error: TypeError: <lambda>() takes 1 positional argument but 2 were given
.
I couldn’t understand reason behind it.
Here’s how you might define sum
if it didn’t exist:
from functools import reduce
def sum(it):
return reduce(lambda acc, val: acc + val, it)
Or:
from functools import reduce
import operator
def sum(it):
return reduce(operator.add, it)
functools.reduce
reduces the values produced by an iterator to a single value by repeatedly combining consecutive values using the function you provide. So the function needs to be able to combine two values and therefore must take two arguments.
So you could define sum_of_squares
using reduce
, like this, although there are a lot of corner cases to cope with:
from functools import reduce
def sum_of_squares(it):
it = iter(it)
try:
first = next(it)
except StopIteration:
return 0
return reduce(lambda acc, val: acc + val * val,
it,
first * first)
Personally, I think the following is clearer:
def sum_of_squares(it):
return sum(map(lambda x: x ** 2, it))
The function
parameter to reduce()
should take two arguments: an old one and a new one. To sum, you’d just need to add them together:
lambda r, x: x**2 + r
However, that doesn’t get the right answer if the first element is >1. You might be thinking reduce()
is like sum(map())
:
def square_sum(numbers):
return sum(map(lambda x: x**2, numbers))
But it’s more readable to replace the map
with a generator expression:
def square_sum(numbers):
return sum(x**2 for x in numbers)
print(square_sum([1, 2, 2])) # -> 9