Reputation:
I'm trying to pair together a bunch of elements in a list to create a final object, in a way that's analogous to making a sum of objects. I'm trying to use a simple variation on reduce
where you consider a list of pairs rather than a flat list to do this. I want to do something along the lines of:
nums = [1, 2, 3]
reduce(lambda x, y: x + y, nums)
except I'd like to add additional information to the sum that is specific to each element in the list of numbers nums
. For example for each pair (a,b) in the list, run the sum as (a+b):
nums = [(1, 0), (2, 5), (3, 10)]
reduce(lambda x, y: (x[0]+x[1]) + (y[0]+y[1]), nums)
This does not work:
>>> reduce(lambda x, y: (x[0]+x[1]) + (y[0]+y[1]), nums)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
TypeError: 'int' object is unsubscriptable
Why does it not work? I know I can encode nums
as a flat list - that is not the point - I just want to be able to create a reduce operation that can iterate over a list of pairs, or over two lists of the same length simultaneously and pool information from both lists. thanks.
Upvotes: 6
Views: 5185
Reputation: 110118
Looking at the lambda you passed to reduce
:
f = lambda x, y: (x[0]+x[1]) + (y[0]+y[1])
The value returned by f
will be passed as a parameter to another invocation of f
. But while f
expects its parameters to be pairs, the value it returns is an int
. You need to make this function return a pair as well. For example, this would sum up the left and right sides separately:
>>> nums = [(1, 0), (2, 5), (3, 10)]
>>> reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), nums)
(6, 15)
Another thing you can do is treat the accumulated value differently from the list elements: You can make the accumulated value an int
, while the list elements are pairs. If you do this, you must pass the initializer
argument to reduce
, so that the accumulator is initialized correctly to an int
:
>>> nums = [(1, 0), (2, 5), (3, 10)]
>>> reduce(lambda acc, y: acc + y[0] + y[1], nums, 0)
21
Upvotes: 6