Search code examples
pythonlambda

"TypeError: <lambda>() takes 1 positional argument but 2 were given" using reduce()


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.


Solution

  • 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))