Reputation: 1421
I was wondering if map can be used at all to sum the elements of a list.
assume a = [1, 2, 3, 4]
list(map(sum, a))
will give an error that int object is not iterable
because list wants iterables.
map(sum, a)
is a valid statement but given the object, I do not see an easy way to dereference it.
[map(sum, a)]
will return an object inside the list
this answer states that it should be easy. What am I missing here?
Upvotes: 5
Views: 48248
Reputation: 71471
map
applies a function to every element in the list. Instead, you can use reduce
:
a = [1, 2, 3, 4]
sum_a = reduce(lambda x, y:x+y, a)
In this case, purely sum
can be used, however, to be more functional, reduce
is a better option.
Or, in Python3:
from functools import reduce
a = [1, 2, 3, 4]
sum_a = reduce(lambda x, y:x+y, a)
Upvotes: 17
Reputation: 11
Indirectly you can add all the elements of a list using a map function using a global variable like below:
# reading the file
with open('numbers.txt') as f:
lines = [line.strip() for line in f]
numbers = [int(line) for line in lines]
all_sum = 0
def add(n):
global all_sum
all_sum += n
return(all_sum)
result = map(add, numbers)
print(list(result)[-1])
There is only one number in one line in the text file.
Upvotes: 0
Reputation: 719
reduce(lambda x,y:x+y, L) #summing all elements of a list L
Using map reduce and printing the elapsed time in seconds
import time
from six.moves import reduce
import numpy as np
start=time.time()
L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = reduce(lambda x,y:x+y, L)
end=time.time()
print("sum of list L ", L, " is equal to", result)
print("elapsed time is ", end-start, ' seconds')
output:
sum of list L [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] is equal to 55
elapsed time is 0.00014519691467285156 seconds
using python's build-in sum function and elapsed time
start=time.time()
s = sum([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
end=time.time()
print("elapsed time is ", end-start, ' seconds')
output:
elapsed time is 9.226799011230469e-05 seconds
sum is a slightly faster method since 9e-05 is less than 1e-04
Upvotes: 1
Reputation: 21
Here's one way to do it purely functionally.
from operator import add
from functools import reduce
result = reduce(add, a)
Upvotes: 2
Reputation: 110611
Of course if one just want to sum the elements of a list, he should simply call sum(list_)
.
Now, comming to your question: map
, both the Python built-in and the pattern refer to applying a function to a data sequence, and yield another sequence, with a separate result for each element in the initial sequence.
sum
does not do that - it yields a single result for the whole sequence. That pattern is called reduce
, and so is the Python ex-built-in to do that. In Python 3, it was "demoted" to the functools
module, as it is rarely used when compared to the map pattern.
The sum
built-in itself employs the "reduce" pattern alone - but if you were to explicitly recreate sum
using the reduce pattern it goes like:
from functools import reduce
a = [1, 2, 3, 4]
reduce(lambda result, value: result + value, a, 0)
The first parameter is a callable that takes the "accumulated result so far", the second value is the sequence of items you want to run reduce at, and the third parameter is the initial value to be passed as the accumulated result. (so,it starts at zero). For a multiplicatory, we could use:
reduce(lambda result, value: result * value, a, 1)
update: Python 3.8 implemented the "multiplicatory" in the standard library as math.prod
.
Upvotes: 7
Reputation: 30605
x = list(map(sum,a))
Is equivalent to
x = []
for i in a:
x.append(sum(i))
Sum needs a iterable to apply sum across. If you see the docs syntax goes this way sum(iterable[, start])
. Since int
is not an iterable you get that error.
Upvotes: 10
Reputation: 779
The error int object is not iterable
is not because list
expects an iterable, but sum
expected an iterable.
The following code:
map(sum , [1,2,3,4])
Is somewhat equivalent to:
[sum(x) for x in [1,2,3,4]]
Executing the last expression yields the same error.
Upvotes: 2