unworthy_enzyme
unworthy_enzyme

Reputation: 23

python reduce method works with length of 2 list but not with length with 3 or more

i have a set of points like this:

points = [[1, 1], [2, 3]]

i want to add up the x-components and y-components separately so i wrote this code

sum_x = reduce(lambda a, b: a[0] + b[0] ,points)
sum_y = reduce(lambda a, b: a[1] + b[1], points)

if i have only 2 points it works but if i add any more points then i get this error:

Traceback (most recent call last):
  File "linear-regression.py", line 29, in <module>
    sum_x = reduce(lambda a, b: a[0] + b[0], points)
  File "linear-regression.py", line 29, in <lambda>
    sum_x = reduce(lambda a, b: a[0] + b[0], points)
TypeError: 'int' object is not subscriptable

Upvotes: 1

Views: 259

Answers (3)

Mark
Mark

Reputation: 92440

Your accumulator should be an integer, not a list. You can initialize it with zero to get it started. If you don't initialize it, the initial value will be the first value in points ([1, 1]), which is not what you want here.

from functools import reduce

points = [[1, 1], [2, 3], [2, 3]]


sum_x = reduce(lambda a, b: a + b[0], points, 0)
# 5
sum_y = reduce(lambda a, b: a + b[1], points, 0)
# 7

Alternatively, you can do this in a single step and return a list of sums:

sum_x, sum_y = reduce(lambda a, b: [a[0] + b[0], a[1] + b[1]], points)

Now passing the initial value in as an accumulator makes sense because the final value is a list.

Upvotes: 3

buran
buran

Reputation: 14233

why not just

points = [[1, 1], [2, 3]]
sum_x, sum_y = map(sum, zip(*points))

this works with arbitrary length list points.

Upvotes: 2

Silvio Mayolo
Silvio Mayolo

Reputation: 70277

Mark's answer fixes your immediate problem, but I want to point something more general out, especially since you tagged (which, at its core, is about decomposing functionality into its irreducible parts). You're performing two operations that you try to treat as one. Your computation can be summarized as

  1. Get the first element of each vector
  2. Sum them

We can split these two steps up.

sum_x = reduce(lambda a, b: a + b, map(lambda x: x[0], points))

And reduce with addition as the operation has a name in Python: sum

sum_x = sum(map(lambda x: x[0], points))

Now our code reads as "get the first elements and sum them".

Upvotes: 3

Related Questions