How can I restart a string iterator endlessly?

1.1k views Asked by At

This question is somewhat related to this, this, and this one. Assume I have two generators/iterators of different lengths:

>>> s = "abcde"
>>> r = range(0, 16)

I now want to repeat iterating over the shorter one until the longer one is exhausted. The standard zip() function terminates once the shorter of the two is exhausted:

>>> for c, i in zip(s, r) :
...     print(c, i)
... 
a 0
b 1
c 2
d 3
e 4

The best I can come up with is wrapping the string into a generator like so:

>>> def endless_s(s) :
...     while True :
...         for c in s :
...             yield c

which gives me the desired result of

>>> _s = endless_s(s)
>>> for c, i in zip(_s, r) :
...     print(c, i)
... 
a 0
b 1
c 2
d 3
e 4
a 5
b 6
c 7
d 8
e 9
a 10
b 11
c 12
d 13
e 14
a 15

Now I wonder: is there a better and more compact way of doing this? Like an endless string join, or some such?

1

There are 1 answers

1
vaultah On BEST ANSWER

You could do this with itertools.cycle:

Make an iterator returning elements from the iterable and saving a copy of each. When the iterable is exhausted, return elements from the saved copy. Repeats indefinitely.

which is able to replace your function entirely:

from itertools import cycle as endless_s