tags:

views:

121

answers:

3

It is very common to write a loop and remember the previous.

I want a generator that does that for me. Something like:

import operator

def foo(it):
    it = iter(it)
    f = it.next()
    for s in it:
        yield f, s
        f = s

Now subtract pair-wise.

L = [0, 3, 4, 10, 2, 3]

print list(foo(L))
print [x[1] - x[0] for x in foo(L)]
print map(lambda x: -operator.sub(*x), foo(L)) # SAME

Outputs:

[(0, 3), (3, 4), (4, 10), (10, 2), (2, 3)]
[3, 1, 6, -8, 1]
[3, 1, 6, -8, 1]
  • What is a good name for this operation?
  • What is a better way to write this?
  • Is there a built-in function that does something similar?
  • Trying to use 'map' didn't simplify it. What does?
+4  A: 
l = [(0,3), (3,4), (4,10), (10,2), (2,3)]
print [(y-x) for (x,y) in l]

Outputs: [3, 1, 6, -8, 1]

Matt Caldwell
The construct used in the print statement is called a "list comprehension."
Matt Caldwell
+2  A: 

Recipe from iterools:

from itertools import izip, tee
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

and then:

>>> L = [0, 3, 4, 10, 2, 3]
>>> [b - a for a, b in pairwise(L)]
[3, 1, 6, -8, 1]

[EDIT]

Also, this works (Python < 3):

>>> map(lambda(a, b):b - a, pairwise(L))
pillmuncher
+1 for the name pairwise and composing it using itertools.
Eddy Pronk
+3  A: 

[y - x for x,y in zip(L,L[1:])]

demas
+1 Why didn't I think of that. I like it a lot.
Eddy Pronk
+1 for simplicity and portability.
Johnsyweb