Search code examples
pythonsequencepython-itertools

How to generate infinite sequence with itertools


I would like to generate two infinitive series of 0 and 1 and specifically in the following order:

0, 1, 0, -1, 0, 1, 0, -1, ...

I have created the following code which does not return what except:

# for in loop
for i in itertools.cycle(range(0,2)):
    if i == 0:
        i += 1
        if i == 1:
            i -= 1
            if i == 0:
                i -= 1
                print(i, end = " ")

It just returns a series of -1. Cannot figure out where the error is. Can anyone give any suggestions


Solution

  • Not sure why you're insisting on using itertools.cycle in a for loop like this, but here's one way you could make this work:

    for i in itertools.cycle(range(0, 2)):
        if i == 0:
            print(i, end=" ")
            i += 1
            print(i, end=" ")
            i -= 1
            print(i, end=" ")
            i -= 1
            print(i, end=" ")
    

    Note that there's really no point in using your nested if statements, since each nested predicate will always be true: if i is zero, and then you add one to it, then of course your nested predicate if i == 1 will be true...

    In addition, your use of itertools.cycle in a for loop is an anti-pattern. As shown in BrokenBenchmark's answer, you can simply cycle over the elements of the sequence itself, forever. If you insist on using the for loop:

    for i in itertools.cycle([0, 1, 0, -1]):
        print(i, end=" ")
    

    There are so many things wrong with this approach though. Namely, as I discussed in the comments, this is an infinite loop which is a fundamentally different behavior than an infinite sequence. With an infinite loop, nothing else can ever happen -- your program will be stuck cycling over your four elements forever with no way to do anything else.

    If you use itertools.cycle as it's meant to be used -- as a generator -- you can pick up where you left off in the sequence at any time, allowing you to perform other tasks for as long as you want before continuing your sequence:

    c = itertools.cycle((0, 1, 0, -1))
    next(c) # 0
    next(c) # 1
    next(c) # 0
    next(c) # -1
    
    # do something else for a while
    next(c) # 0
    
    # yield the next 10 items from the sequence
    for _ in range(10):
        print(next(c), end=" ")
    
    # do something else again