On Wed, 08 Feb 2012 01:10:28 +0000, Mark Lawrence wrote: > I'm looking at a way of cycling around a sequence i.e. starting at some > given location in the middle of a sequence and running to the end before > coming back to the beginning and running to the start place.
If you have a sequence, and don't mind copying it, the easiest way is just to slice and join: >>> a = range(20) >>> b = a[5:] + a[:5] >>> print b [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4] Short, sweet, easy and simple. What's not to like about it? For small (say, less than a few thousand of items) sequences, this probably is the fastest way to do it. Handling this lazily is trickier than it seems, because you have to store the first N items somewhere until you get to the rest of the iterable. There is no Right Way to do it, since the best solution will depend on how many items you have and how large N is. Here's one way with itertools: >>> from itertools import islice, chain, tee >>> a = iter(range(20)) >>> t1, t2 = tee(a) >>> b = chain(islice(t1, 5, None), islice(t2, None, 5)) >>> print list(b) [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4] But read the docs for tee first: it may be that converting to a list is faster and more memory efficient. http://docs.python.org/library/itertools.html#itertools.tee Using tee may be overkill. Here's a simpler way: >>> a = iter(range(20)) >>> t = list(islice(a, 5)) >>> b = chain(a, t) >>> list(b) [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4] If your data is truly humongous, already stored in a list, and you don't want to make a copy, then I recommend your trick of generating the indexes: def cycle(seq, n): for indexes in (xrange(n, len(seq)), xrange(n)): for i in indexes: yield seq[i] If your data is humongous but only available lazily, buy more memory :) -- Steven -- http://mail.python.org/mailman/listinfo/python-list