George
George

Reputation: 5681

optimize sum by every 2 elements in list

I have a list:

mylist = [0.01, 0.09, 0.04, 0.16]

I want to take the sum every two elements, so my result will be: [0.1, 0.2]

I figured this solution:

chunks = [mylist[i:i + 2] for i in range(0, len(mylist), 2)]

temp = []
for i in chunks:
    s = 0
    for j in i:
        s += j
    temp.append(s)

print(temp)

[0.1, 0.2]

but I was wondering if there is a better solution avoiding the 2 for loops.

Upvotes: 0

Views: 8880

Answers (5)

Mauro Lacy
Mauro Lacy

Reputation: 389

map(sum, zip(mylist[::2], mylist[1::2]))

For lists of odd length, use zip_longest instead

from itertools import zip_longest as zipl
map(sum, zipl(mylist[::2], mylist[1::2], fillvalue=0))

Upvotes: 1

MSeifert
MSeifert

Reputation: 152647

Using iteration_utilities.grouper:

>>> from iteration_utilities import grouper
>>> mylist = [0.01, 0.09, 0.04, 0.16]
>>> [sum(group) for group in grouper(mylist, 2)]  # or "list(map(sum, grouper(mylist, 2)))"
[0.09999999999999999, 0.2]

That the first value isn't 0.1 is because of floating point arithmetic, the other solutions here are similarly affected.

This should be as fast as the other approaches, maybe even faster (except for the numpy-solution).

Upvotes: 1

Zobia Khawaja
Zobia Khawaja

Reputation: 31

You can try this (Will work for both even and odd lengths):

import itertools as it    
[sum(r) for r in it.izip_longest(mylist [::2], mylist [1::2], fillvalue=0)]

Upvotes: 1

Yuval Atzmon
Yuval Atzmon

Reputation: 5945

Some people might consider it an overkill, however once you go into calculations over arrays of numbers, numpy is your friend. It enables you to make such calculations in a readable and efficient manner.

import numpy as np
x = np.array([0.01, 0.09, 0.04, 0.16])
# reshaping the array to a 2D array, and summing over the columns
x.reshape((x.shape[0]/2,2)).sum(axis=1)

Upvotes: 5

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476614

Why not simply use the sum(..) builtin:

temp = [sum(mylist[i:i+2]) for i in range(0, len(mylist), 2)]

This is a one-liner that clearly is more Pythonic. Furthermore it is probably more efficient since here you do not store all slices into memory first, etc. but you directly calculate the sum.

Upvotes: 9

Related Questions