Aguy
Aguy

Reputation: 8059

A neat way to create an infinite cyclic generator?

I want a generator that cycle infinitely through a list of values.

Here is my solution, but I may be missing a more obvious one.

The ingredients: a generator function that flatten an infinitely nested list, and a list appendant to itself

def ge(x):
    for it in x:
        if isinstance(it, list):
            yield from ge(it)
        else:
            yield(it)


def infinitecyclegenerator(l):
    x = l[:]
    x.append(x)
    yield from ge(x)

The use:

g = infinitecyclegenerator([1,2,3])

next(g) #1
next(g) #2
next(g) #3
next(g) #1
next(g) #2
next(g) #3
next(g) #1
...

As I said, I may be missing a trivial way to do the same and I'll be happy to learn. Is there a neater way?

Also, should I worry about memory consumption with all the mind boggling infinities going on here, or is everything cool with my code?

Upvotes: 2

Views: 366

Answers (2)

Aguy
Aguy

Reputation: 8059

It must be the hour :-). The one obvious way I realized after posting:

def infinitecyclegenerator(l):
    while True:
        for it in l:
            yield it

Sorry for missing the obvious.

Upvotes: 0

Moses Koledoye
Moses Koledoye

Reputation: 78556

You can use itertools.cycle to achieve the same result

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.

Emphasis mine. Your only concern about memory would be saving a copy of each item returned by the iterator.

>>> from itertools import cycle
>>> c = cycle([1,2,3])
>>> next(c)
1
>>> next(c)
2
>>> next(c)
3
>>> next(c)
1
>>> next(c)
2
>>> next(c)
3

Upvotes: 7

Related Questions