1

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]
Community
  • 1
  • 1
bluegray
  • 600
  • 8
  • 18

6 Answers6

4
>>> 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)]
Katriel
  • 114,760
  • 19
  • 131
  • 163
  • 1
    with `itertools.islice` for sufficiently large lists of course. – aaronasterling Oct 31 '10 at 09:48
  • 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 Oct 31 '10 at 12:41
  • 1
    @jsbueno -- true but irrelevant, the point is to pair up items in the list not to get an index over an iterable. @aaron: indeed! – Katriel Oct 31 '10 at 14:31
2

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
  • 6,304
  • 1
  • 30
  • 32
1

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
  • 313,408
  • 56
  • 485
  • 544
  • 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 Oct 31 '10 at 09:58
1
for i, j in zip(values, values[1:]):
     j - i
SilentGhost
  • 287,765
  • 61
  • 300
  • 288
1
diff = [values[i+1] - values[i] for i in range(len(values)-1)]
Sven Marnach
  • 530,615
  • 113
  • 910
  • 808
0
[y - x for x,y in zip(L,L[1:])]
ceth
  • 42,340
  • 57
  • 170
  • 277