I am having problem with functools.reduce(). It returns int object is not subscriptable
total_population = functools.reduce(lambda a, b: a[0] + b[0], mid_points)
variable 'mid_points' list of tuples: sample is given in picture below
But when I tried above line of code on:
li = [(1,"a"), (2,"b")]
it gives correct output i.e 3
Please help! what am I do?
The result of reduce
needs to be a valid input to the reduction function; you reduction function expects a sequence with at least one element, but you're returning an int
. Just change the code to:
[total_population] = functools.reduce(lambda a, b: (a[0] + b[0],), mid_points)
to add a layer of tuple
wrapping so indexing continues to work, and the brackets at the end unpack the resulting single element tuple
. This will break if mid_points
is a single element, so if that's possible:
total_population, *_ = functools.reduce(lambda a, b: (a[0] + b[0],), mid_points)
is slightly safer, as it just captures any extra elements in the result into an ignored list
.
An alternative (thanks for reminding me @deceze) is to give reduce
a starting value, so a
is always an int
, both on the first call and all subsequent calls:
total_population = functools.reduce(lambda a, b: a + b[0], mid_points, 0)
The final argument to reduce
is the first a
and all subsequent a
s are results of previous calls. Of course, this can also be simplified in a third way to avoid reduce
entirely:
from operator import itemgetter
total_population = sum(map(itemgetter(0), mid_points))
# Or without an import, but ever-so-slightly slower:
total_population = sum(pt[0] for pt in mid_points)
since really you just need to do two things; extract the first element of each input, and sum them.