#285 · Iterators and generators · Intermediate · 65 XP · about 12 min
The corners of a fence, the stops of a bus route, the readings of a thermometer: often you need each item together with the one after it.
Write a generator pairwise(iterable, wrap=False) that yields a tuple (a, b) for every two neighbouring items, in order. If wrap is True, it then yields one last pair (last, first) that closes the loop, like the final side of a polygon.
An iterable with fewer than two items has no pairs, even when wrap is True.
It must be lazy: it reads each item only when it is needed and never goes back to the start of iterable (which may be a generator that can be read only once), so it also works on endless iterables.
list(pairwise([1, 2, 3])) # returns [(1, 2), (2, 3)] list(pairwise('abc', wrap=True)) # returns [('a', 'b'), ('b', 'c'), ('c', 'a')] list(pairwise([7])) # returns [] from itertools import count, islice list(islice(pairwise(count()), 3)) # returns [(0, 1), (1, 2), (2, 3)]
First solves only, ranked by stars and then time.