Yesh
Yesh

Reputation: 1194

Why does Python's reduce raise a TypeError when used to sum a list of lists?

I was under the impression that I would get the sum of elements in lists of a list if I used reduce as follows:

reduce(lambda x, y: x[0]+y[0], [[1],[2],[3],[4],[5]])

However I get the error saying:

TypeError: 'int' object has no attribute '__getitem__'

What is reduce doing in this case? And if I do want to sum, what is the best way that avoids a for loop?

Upvotes: 1

Views: 159

Answers (2)

wim
wim

Reputation: 362766

If you want to use reduce like that, you'll have to provide the initial value:

>>> list_of_lists = [[1],[2],[3],[4],[5]]
>>> reduce(lambda x, y: x+y[0], list_of_lists, 0)
15

But don't use reduce for this. Just use sum built-in:

>>> sum(n for sublist in list_of_lists for n in sublist)
15
>>> sum(n for [n] in list_of_lists)  # enforcing 1-element sublists
15

Upvotes: 2

Silvio Mayolo
Silvio Mayolo

Reputation: 70277

There's not really much reason to throw everything in a sublist. This is really what you're going for.

reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])

If all you're doing is summing elements of a list, Python has a built-in for that.

sum([1, 2, 3, 4, 5])

If you really have some reason to need lists of lists, then you need the accumulated value to be a list as well. Think of it this way: the function you pass to reduce should usually return a value of the same "type" (using the word "type" very loosely here) as the first argument, as it will be later passed in as the first argument to another call.

reduce(lambda x, y: [x[0]+y[0]], [[1], [2], [3], [4], [5]])

Upvotes: 0

Related Questions