I would say that the most pythonic and easy to read solution would be something like this:
import itertools def neighbours(items, fill=None): """Yeild the elements with their neighbours as (before, element, after). neighbours([1, 2, 3]) --> (None, 1, 2), (1, 2, 3), (2, 3, None) """ before = itertools.chain([fill], items) after = itertools.chain(items, [fill])
What we can use like this:
>>> l = ['a', '>>', 'b', '>>', 'd', 'e', 'f', 'g', '>>', 'i', '>>', '>>', ... 'j', 'k', 'l', '>>', '>>'] >>> print(list(split_not_neighbour(l, ">>"))) [['a', 'b', 'd'], ['g', 'i', 'j'], ['l']]
Pay attention to the careful avoidance of any direct indexing.
Edit: a more elegant version.
def split_not_neighbour(seq, mark): """Split the sequence on each item where the item is not the mark, or next to the mark. split_not_neighbour([1, 0, 2, 3, 4, 5, 0], 0) --> (1, 2), (5) """ neighboured = neighbours(seq) for _, items in itertools.groupby(neighboured, key=lambda x: mark not in x): yield [item for _, item, _ in items if item != mark]