views:

102

answers:

6

Possible Duplicate:
Python: Looping through all but the last item of a list

Is there a better way of iterating through a list when you also need the next item (or any other arbitrary item) in the list? I use this, but maybe someone can do better...

values = [1, 3, 6, 7 ,9]
diffs = []
for i in range(len(values)):
    try: diffs.append(values[i+1] - values[i])
    except: pass

print diffs

gives:

[2, 3, 1, 2]
+1  A: 

You could use

for pos, item in enumerate(values):
    try:
        diffs.append(values[pos+1] - item)
    except IndexError:
        pass

although in your case (since you're just looking for the next value), you could also simply use

for item,nextitem in zip(values, values[1:]):
    diffs.append(nextitem-item)

which can also be expressed as a list comprehension:

diffs = [nextitem-item for item,nextitem in zip(values, values[1:])]
Tim Pietzcker
deleted my earlier comment. If the list is longer than about 100 elements, then this is indeed cheaper than an `if`. So that's not 'very large' as I claimed was necessary for efficiency earlier. Sorry for the confusion.
aaronasterling
+4  A: 
>>> values = range(10)
>>> values
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> zip(values[0:],values[1:])
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)]
katrielalex
with `itertools.islice` for sufficiently large lists of course.
aaronasterling
Although this works in this case, the way to go for getting an item index and the item is to use the "enumerate" generator - check @Tim Pietzcker's answer
jsbueno
@jsbueno -- true but irrelevant, the point is to pair up items in the list not to get an index over an iterable. @aaron: indeed!
katrielalex
+1  A: 
for i, j in zip(values, values[1:]):
     j - i
SilentGhost
For big lists and Python 2.x, itertools.izip might be more efficient.
Sven Marnach
+1  A: 
diff = [values[i+1] - values[i] for i in range(len(values)-1)]
Sven Marnach
+2  A: 

what about with the aid of pairwise recipe from itertools document

from itertools import tee, izip

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)
def main():
    values = [1, 3, 6, 7 ,9]
    diffs = [post - prior for prior, post in pairwise(values)]
    print diffs


if __name__ == "__main__":
    main()

output
[2, 3, 1, 2]

sunqiang
A: 
[y - x for x,y in zip(L,L[1:])]
demas
you haven't seen previous answers, have you?
SilentGhost