Reputation: 69
I would like to know if there exists a base solution to do something like this:
for n in range(length=8, start_position= 3, direction= forward)
The problem I'm encountering is I would like the loop to continue past the final index, and pick up again at idx =0, then idx=1, etc. and stop at idx= 3, the start_position.
To give context, I seek all possible complete solutions to the n-queen problem.
Upvotes: 1
Views: 87
Reputation: 54163
You could implement this for an arbitrary iterable by using itertools.cycle
.
from itertools import cycle
def circular_iterator(iterable, skip=0, length=None, reverse=False):
"""Produces a full cycle of @iterable@, skipping the first @skip@ elements
then tacking them on to the end.
if @iterable@ does not implement @__len__@, you must provide @length@
"""
if reverse:
iterable = reversed(iterable)
cyc_iter = cycle(iterable)
for _ in range(skip):
next(cyc_iter, None)
if length:
total_length = length
else:
total_length = len(iterable)
for _ in range(total_length):
yield next(cyc_iter, None)
>>> lst = [x for x in range(1, 9)]
# [1, 2, 3, 4, 5, 6, 7, 8]
>>> list(circular_iterator(lst, skip=3))
[4, 5, 6, 7, 8, 1, 2, 3]
Upvotes: 0
Reputation: 2895
def loop_around_range(length, start_position, direction='forward'):
looped_range = [k % length for k in range(start_position, start_position+length)]
if direction == 'forward':
return looped_range
else:
return looped_range[::-1]
Upvotes: 0
Reputation: 372724
Another option for solving this is to use modular arithmetic. You could do something like this, for example:
for i in range(8)
idx = (i + 3) % 8
# use idx
This easily can be generalized to work with different lengths and offsets.
Upvotes: 1
Reputation: 57033
Based on your latest edit, you need a "normal" range and the modulo operator:
for i in range(START, START + LEN):
do_something_with(i % LEN)
Upvotes: 5
Reputation: 10959
from itertools import chain
for n in chain(range(3,8), range(3)):
...
The chain()
returns an iterator with 3, 4, ..., 7, 0, 1, 2
Upvotes: 3