li = [0, 1, 2, 3]
running = True
while running:
for elem in li:
thiselem = elem
nextelem = li[li.index(elem)+1]
Когда это достигает последнего элемента, IndexError
повышен (как имеет место для любого списка, кортежа, словаря, или представьте в виде строки, который выполнен с помощью итераций). Я на самом деле хочу в той точке для nextelem
равняться li[0]
. Мое довольно громоздкое решение этого было
while running:
for elem in li:
thiselem = elem
nextelem = li[li.index(elem)-len(li)+1] # negative index
Существует ли лучший способ сделать это?
После тщательного обдумывания я думаю, что это лучший способ. Он позволяет легко выйти посередине, не используя перерыв
, что я считаю важным, и требует минимальных вычислений, так что я думаю, что это самый быстрый способ. Также не требуется, чтобы li
был списком или кортежом. Это может быть любой итератор.
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)
Я оставляю другие решения здесь для потомков.
Все эти причудливые итераторы имеют свое место, но не здесь. Используй оператор %.
li = [0, 1, 2, 3]
running = True
while running:
for idx, elem in enumerate(li):
thiselem = elem
nextelem = li[(idx + 1) % len(li)]
Теперь, если вы собираетесь бесконечно перебирать список, то просто сделайте так:
li = [0, 1, 2, 3]
running = True
idx = 0
while running:
thiselem = li[idx]
idx = (idx + 1) % len(li)
nextelem = li[idx]
Я думаю, что это проще понять, чем другое решение, включающее тройку
, и, возможно, тоже быстрее. Если вы уверены, что список не изменит размера, вы можете пропустить копию len(li)
и использовать ее.
Это также позволит вам легко сойти с колеса обозрения в середине, вместо того, чтобы ждать, пока ведро снова опустится на дно. В других решениях (в том числе и в Вашем) необходимо проверить работающую
в середине петли на наличие
, а затем ломать
.
while running:
for elem,next_elem in zip(li, li[1:]+[li[0]]):
...
Можно использовать парный циклический итератор:
from itertools import izip, cycle, tee
def pairwise(seq):
a, b = tee(seq)
next(b)
return izip(a, b)
for elem, next_elem in pairwise(cycle(li)):
...
while running:
lenli = len(li)
for i, elem in enumerate(li):
thiselem = elem
nextelem = li[(i+1)%lenli]