I need to cycle through a list for starting position between 1-4
using itertools
I am able to cycle through the list
positions = it
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.
Use slices of the original list:
In [15]: def custom_slice(lst, start):
....: return cycle(lst[start:] + lst[:start + 1])
Demo:
In [16]: positions = custom_slice(lst, 2)
In [17]: next(positions)
Out[17]: 3
In [18]: next(positions)
Out[18]: 4
In [19]: next(positions)
Out[19]: 1
In [20]: next(positions)
Out[20]: 2