I am trying to make an iterator that goes "backwards" too. Itertools cycle provides a similar function cycle(range(3)) and the next function produces 0,1,2,0,1,2. However, I would like 0,1,2,1,0,1,2,1,0,1,2....

I tried using iter tools cycle. Here is the code.

from itertools import cycle
myIterator = cycle(range(3))

print(next(myIterator))
print(next(myIterator))
print(next(myIterator))
print(next(myIterator))

Output: 0 1 2 0

2

There are 2 best solutions below

3
Brian61354270 On

Just pass the sequence you want to cycle to cycle:

it = cycle([0, 1, 2, 1])

For an arbitrary list, you can use

from itertools import cycle, islice
forward_list = list(range(5))

it = cycle(forward_list + forward_list[-2:1:-1])

print(list(islice(it, 15)))

which outputs

[0, 1, 2, 3, 4, 3, 2, 0, 1, 2, 3, 4, 3, 2, 0]
0
Alain T. On

You could write a function that returns the infinite generator that cycles up and down using chain and cycle from itertools:

from itertools import chain,islice,cycle

def upDown(N): return cycle(chain(range(N),range(N-2,0,-1)))    

output:

from itertools import islice
print(*islice(upDown(5),17))

0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0

If you don't want to import anything, the function can be a generator itself using basic constructs:

def upDown(N):
    while True:
        yield from range(N)
        yield from range(N-2,0,-1)

If you don't mind the cycle starting on its highest value, you can write the function like this:

def wave(N):
    while True:
        yield from map(abs,range(1-N,N-1))

output:

print(*islice(wave(5),17))

4 3 2 1 0 1 2 3 4 3 2 1 0 1 2 3 4

print(*islice(wave(5),4,21))

0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0