Iterate with a tuple and multiple defaulted previous and next elements

In general pythons iterators are a nice way to iterate fast and source-code-clean over iterable. Sadly you can always only iterate over a single element. In general they are not really flexible (for example an iterator can not go back).

Sometimes you need to iterate not only with a single element but rather with a tuple of elements; therefore multiple previous and next elements to your current. There is always the problem what to do with your previous and next element at the borders or on which place of your tuple the iterator has to start and and end. Often calculations with the index are used, but this gets fast very ugly since you have maybe multiple border conditions and not every python iterable has also an index.

An stackoverflow question discuss multiple options, but none of them a general simple and nice generator. So I programmed a general version myself, which I called surround() (surround because previous and next elements surround the current element; another guy has this called neighbourhood). My version is able to define arbitrary many previous and next elements and you can define which of them can leave the bounds if your iterable or not.

The more nice version more based on itertools can be found here.

The more primitive, maybe for human better understanding version can be found here.

The interfaces of both versions are equivalent and I don't think the other one is more efficient then the other, maybe I should test this ....

The function contains a good documentation, but the fastest way to show how it works, are some examples:

>>> for (prev, curr, next) in surround([1, 2, 3, 4], 1, [2], 2, default=0):
...     print(prev, curr, next)
0 (1, 2) (3, 4)
1 (2, 3) (4, 0)
2 (3, 4) (0, 0)

>>> it = surround([1, 2, 3, 4], "p1, p2, p3", ["c1, c2"], "n1, n2", default=0)
>>> for (prev, curr, next) in it:
...     print(prev, curr, next)
(0, 0, 0) (1, 2) (3, 4)
(0, 0, 1) (2, 3) (4, 0)
(0, 1, 2) (3, 4) (0, 0)

User login