li = [0, 1, 2, 3] running = True while running: for elem in li: thiselem = elem nextelem = li[li.index(elem)+1]
When this reaches the last element, an
IndexError is raised (as is the case for any list, tuple, dictionary, or string that is iterated). I actually want at that point for
nextelem to equal
li. My rather cumbersome solution to this was
while running: for elem in li: thiselem = elem nextelem = li[li.index(elem)-len(li)+1] # negative index
Is there a better way of doing this?
After thinking this through carefully, I think this is the best way. It lets you step off in the middle easily without using
break, which I think is important, and it requires minimal computation, so I think it’s the fastest. It also doesn’t require that
li be a list or tuple. It could be any iterator.
from itertools import cycle li = [0, 1, 2, 3] running = True licycle = cycle(li) # Prime the pump nextelem = next(licycle) while running: thiselem, nextelem = nextelem, next(licycle)
I’m leaving the other solutions here for posterity.
All of that fancy iterator stuff has its place, but not here. Use the % operator.
li = [0, 1, 2, 3] running = True while running: for idx, elem in enumerate(li): thiselem = elem nextelem = li[(idx + 1) % len(li)]
Now, if you intend to infinitely cycle through a list, then just do this:
li = [0, 1, 2, 3] running = True idx = 0 while running: thiselem = li[idx] idx = (idx + 1) % len(li) nextelem = li[idx]
I think that’s easier to understand than the other solution involving
tee, and probably faster too. If you’re sure the list won’t change size, you can squirrel away a copy of
len(li) and use that.
This also lets you easily step off the ferris wheel in the middle instead of having to wait for the bucket to come down to the bottom again. The other solutions (including yours) require you check
running in the middle of the
for loop and then