I sometimes need to iterate a list in Python looking at the "current" element and the "next" element. I have, till now, done so with code like:
for current, next in zip(the_list, the_list[1:]):
# Do something
This works and does what I expect, but is there’s a more idiomatic or efficient way to do the same thing?
Some answers to this problem can simplify by addressing the specific case of taking only two elements at a time. For the general case of N elements at a time, see Rolling or sliding window iterator?.
The documentation for 3.8 provides this recipe:
For Python 2, use
itertools.izipinstead ofzipto get the same kind of lazy iterator (zipwill instead create a list):How this works:
First, two parallel iterators,
aandbare created (thetee()call), both pointing to the first element of the original iterable. The second iterator,bis moved 1 step forward (thenext(b, None)) call). At this pointapoints to s0 andbpoints to s1. Bothaandbcan traverse the original iterator independently – the izip function takes the two iterators and makes pairs of the returned elements, advancing both iterators at the same pace.Since
tee()can take annparameter (the number of iterators to produce), the same technique can be adapted to produce a larger "window". For example:Caveat: If one of the iterators produced by
teeadvances further than the others, then the implementation needs to keep the consumed elements in memory until every iterator has consumed them (it cannot ‘rewind’ the original iterator). Here it doesn’t matter because one iterator is only 1 step ahead of the other, but in general it’s easy to use a lot of memory this way.