# Making the case for repeat

pataphor pataphor at gmail.com
Thu Jun 4 15:37:45 CEST 2009

```This probably has a snowballs change in hell of ending up in builtins or
even some in some module, but such things should not prevent one to
try and present the arguments for what one thinks is right. Else one
would end up with consequentialism and that way lies madness and
hyperreality.

So here is my proposed suggestion for a once and for all reconciliation
of various functions in itertools that can not stand on their own and
keep a straight face. Because of backwards compatibility issues we
cannot remove them but we can boldly jump forward and include the right
repeat in the builtin namespace, which I think would be the best thing.
Alternatively -- the second best solution -- would be to give this
function its own namespace where it can supersede the old incongruencies
in itertools. Combiniter or combinator?

P.

from itertools import count
from functools import partial

def repeat(iterable, cycles = None, times = 1):
L = []
for x in iterable:
for i in xrange(times):
yield x
L.append(x)
counter = count if cycles is None else partial(xrange,cycles-1)
for _ in counter():
for x in L:
for i in xrange(times):
yield x

def test():
#making the case for repeat
from itertools import islice, cycle
times = 2
n = 3
cycles = 2
L = range(n)
#look ma, no islice!
print list(repeat(L, cycles))
print list(repeat(L, cycles, times))
#repeat without extra args works like itertools.cycle:
print list(islice(repeat(L),len(L)*cycles))
print list(islice(cycle(L),len(L)*cycles))
#enclosing a single item in a list emulates
#itertools.repeat functionality:
print list(repeat(['Mr. Anderson'],cycles))

if __name__ == '__main__':
test()

```