简体   繁体   中英

"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.

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, 0)

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 actually do what you want because the first element never gets squared (so it 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM