I need to cycle through a list for starting position between 1-4
using itertools
I am able to cycle through the list
positions = itertools.cycle([1,2,3,4])
next(positions)
This does return the next position, but what if the next time I need to start at 3? How can I set the start position?
I need the start position to change often, I cant just change the list to start at 3.
There's an easy way to generate this sequence with the itertools. cycle() function. This function takes an iterable inputs as an argument and returns an infinite iterator over the values in inputs that returns to the beginning once the end of inputs is reached.
The cycle() function accepts an iterable and generates an iterator, which contains all of the iterable's elements. In addition to these elements, it contains a copy of each element.
In repeat() we give the data and give the number, how many times the data will be repeated. If we will not specify the number, it will repeat infinite times. In repeat(), the memory space is not created for every variable.
itertools. count() makes an iterator that returns values that counts up or down infinitely. By default, it starts at 0 and increases by 1 . You can specify the starting value with the first argument start and the increment with the second argument step .
You can't set a starting position; it'll always start where the given sequence starts.
You can move the cycle along a few steps before you use it for whatever you need it for. Use itertools.islice()
to skip some items:
from itertools import islice
starting_at_three = islice(positions, 2, None)
You pass in the iterable, then a start and stop value; None
here means that the islice()
iterator continues forever or until the underlying positions
iterator is exhausted.
Demo:
>>> from itertools import islice, cycle
>>> positions = cycle([1, 2, 3, 4])
>>> starting_at_three = islice(positions, 2, None)
>>> next(starting_at_three)
3
>>> next(starting_at_three)
4
>>> next(starting_at_three)
1
The other option is to pass in a different sequence; you could pass in [3, 4, 1, 2]
for example.
You can use itertools.islice
for that:
from itertools import cycle
from itertools import islice
positions3 = islice(cycle([1,2,3,4]),2,None)
this will result in a generator that emits 3,4,1,2,3,4,1,2,3,4,...
In case the start position k
is large (compared to the length of the original list), it can pay off to perform a modulo first:
from itertools import cycle
from itertools import islice
source_list = [1,2,3,4]
k = 10000000 # offset index
positions_k = islice(cycle(source_list),k%len(source_list),None)
This will generate an equivalent result, but islice
will not drop the first 10M elements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With