I'm trying to get the sum of all numbers for each list through itertool accumulate function: This is the code:
from itertools import *
import operator
list_numbers = [[45,43,56,67],[41,423,526,627,897],[545,453,656,667]]
Iterable_list = iter(list_numbers)
while(True):
try:
print(list(accumulate(next(Iterable_list),operator.add))[-1])
except StopIteration as ex:
print(ex)
break
The above works well.
if I try to take out the max of each list:
while(True):
try:
print(list(accumulate(next(Iterable_list),func=max))[-1])
except StopIteration as ex:
print(ex)
break
this also works well.
My interpretation was, if I use func = sum
, it will do the sum of each list like I tried below but it prompts error
message:
'int' object is not iterable
while(True):
try:
print(list(accumulate(next(Iterable_list),func=sum))[-1])
except StopIteration as ex:
print(ex)
break
Why it doesn't it work and in which scenario can we use func = sum
?
CodePudding user response:
You could understand better the behavior of itertools.accumulate
if you use a lambda function to explore the inputs that func
will receive.
Let's use lambda x: print(x)
instead of sum
first, to print the values:
TypeError: <lambda>() takes 1 positional argument but 2 were given
Ok, so func
will receive two values. Let's try lambda x, y: print(x, y)
:
45 43
None 56
None 67
None
41 423
None 526
None 627
None 897
None
545 453
None 656
None 667
None
Why are we seeing
None
? Becauseprint()
does not return any value, so it returns aNone
.
This means that func
should receive two values from the iterator (L1 and L2), apply an operation on both values and return a single value C. Then, apply the same operation on the previous result (C) with the next value in the iterator (L3).
Why sum()
fails?
Well, because it expects a single argument, an iterable, and optionally accepts a second (start
). Now, itertools.accumulate
is passing two values and Python assumes you're trying to use sum(L1, start=L2)
, but L1
is not iterable since its just a number... TypeError: 'int' object is not iterable
.
In which scenario can we use func=sum
?
sum()
could help us if it could receive two values and return a single one, which is possible (sum(iterable, start=start)
). Now, consider that the output of sum
will be used as the first input of sum
with the next element in the iterable, something like: sum(sum(L1, start=L2), start=L3)
and so on. This means that sum(L1, start=L2)
should return an iterable for us to be able to use sum
. It's hard to find an example for this, meaning that sum
might not be the best option for any particular case when using itertools.accumulate
, but this doesn't mean that sum
is not useful by itself.
CodePudding user response:
This can be done using Zip() or map() method or using numpy.
Using zip():
def nested_sum(lst):
return [sum(i) for i in zip(*lst)]
lst = [[2, 4, 6], [2, 2, 1], [1, 2, 3]] # A Sample List
print(nested_sum(lst))
#Output
[12,5,6]