4

How to add two consecutive number in the list.

l = [1,2,3,4,5,6,7,8,9]

result = [3,7,11,15,9]

l = [1,2,3,4,5,6,7,8,9,10]

result = [3,7,11,15,19]

I can easily achieve it using simple for loop. But How can I achieve it using more pythonic way.

user12345
  • 2,400
  • 8
  • 33
  • 40
  • 1
    I think that using a simple `for` loop for this problem is as Pythonic as it gets. – NPE Feb 06 '12 at 14:33

6 Answers6

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

returns awaited values for both odd and even numbers:

l = [1,2,3,4,5,6,7,8,9]    # [3, 7, 11, 15, 9]
l = [1,2,3,4,5,6,7,8,9,10] # [3, 7, 11, 15, 19]

UPDATE: if the original list is really large, you can replace the simple slices with islice:

[sum(r) for r in it.izip_longest(it.islice(l,0,None,2), it.islice(l,1,None,2), fillvalue=0)]

UPDATE 2: even a shorter and more universal version (without itertools) comes here:

l = [1,2,3,4,5,6,7,8,9,10]
n = 3

[sum(l[i:i+n]) for i in xrange(0, len(l), n)]
# returns: [6, 15, 24, 10]
eumiro
  • 207,213
  • 34
  • 299
  • 261
6

You can use iterators to avoid intermediate lists:

>>> it = iter([1,2,3,4,5,6,7,8,9,10])
>>> [i + next(it, 0) for i in it]
[3, 7, 11, 15, 19]

It will also work with [1,2,3,4,5,6,7,8,9] because next will return zero on StopIteration.

JBernardo
  • 32,262
  • 10
  • 90
  • 115
3

Best way!

I want to change my answer to this now. I like it more than the itertools solutions; I think it's the least code (if you count importing itertools):

>>> x
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> if len(x) % 2: x.append(0)
... 
>>> map(sum, zip(x[::2], x[1::2]))
[3, 7, 11, 15, 9]

I know some people don't like map, but I like it :) I remember reading somewhere that it's faster than list iterations.


My original answer:

>>> x=[1,2,3,4,5,6,7,8,9,10]
>>> [a+b for a,b in zip(x[::2], x[1::2])]
[3, 7, 11, 15, 19]

But doesn't give your answer for oddly numbered lists:

>>> x=[1,2,3,4,5,6,7,8,9]
>>> [a+b for a,b in zip(x[::2], x[1::2])]
[3, 7, 11, 15]

kludge fix:

>>> x   
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> result = [a+b for a,b in zip(x[::2], x[1::2])]
>>> if len(x) % 2: result.append(x[-1])
... 
>>> print result
[3, 7, 11, 15, 9]

:)

matiu
  • 7,469
  • 4
  • 44
  • 48
1

A Pythonic and efficient way is this, as it only ever iterates over the list once:

In [1]: l = [1,2,3,4,5,6,7,8,9]
In [2]: from itertools import izip_longest
In [3]: [sum (t) for t in izip_longest(* 2 * [iter(l)], fillvalue=0)]
Out[3]: [3, 7, 11, 15, 9]

See: How does zip(*[iter(s)]*n) work in Python? for explanations as to that strange "2-iter over the same list" syntax.


Timing:

% python -m timeit -c 'l = [1,2,3,4,5,6,7,8,9]
from itertools import izip_longest
[sum (t) for t in izip_longest(* 2 * [iter(l)], fillvalue=0)]
'
100000 loops, best of 3: 9.42 usec per loop
Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
0

Write nsplit to split a list (n items a group):

>>> ls = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> nsplit = lambda s, n: [s[i:i+n] for i in range(0, len(s), n)]

# [1+2, 3+4, 5+6, 7+8, 9]
>>> [sum(x) for x in nsplit(ls, 2)]
[3, 7, 11, 15, 9]

# [1+2+3, 4+5+6, 7+8+9]
>>> [sum(x) for x in nsplit(ls, 3)]
[6, 15, 24]

# [1+2+3+4, 5+6+7+8, 9]
>>> [sum(x) for x in nsplit(ls, 4)]
[10, 26, 9]
kev
  • 155,172
  • 47
  • 273
  • 272
0
from itertools import chain

l = [1,2,3,4,5,6,7,8,9]
it = chain(l,[0])
result = list(x + next(it) for x in it)
print l,'\n',result,'\n'


l = [1,2,3,4,5,6,7,8,9,10]
it = chain(l,[0])
result = list(x + next(it) for x in it)
print l,'\n',result,'\n'



l = [1,2,3,4,5,6,7,8,9]
it = chain(l,[0,0])
result = list(x + next(it) + next(it) for x in it)
print l,'\n',result,'\n'

l = [1,2,3,4,5,6,7,8,9,10]
it = chain(l,[0,0])
result = list(x + next(it)+ next(it) for x in it)
print l,'\n',result,'\n'

produces

[1, 2, 3, 4, 5, 6, 7, 8, 9] 
[3, 7, 11, 15, 9] 

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
[3, 7, 11, 15, 19] 

[1, 2, 3, 4, 5, 6, 7, 8, 9] 
[6, 15, 24] 

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
[6, 15, 24, 10]

But I prefer the JBernardo - glglgl 's solution

eyquem
  • 26,771
  • 7
  • 38
  • 46