Obtener el siguiente elemento mientras recorres una lista

li = [0, 1, 2, 3] running = True while running: for elem in li: thiselem = elem nextelem = li[li.index(elem)+1] 

Cuando esto llega al último elemento, se IndexError un IndexError (como es el caso de cualquier lista, tupla, diccionario o cadena que se itera). De hecho, en ese momento quiero que nextelem igual a li[0] . Mi solución bastante incómoda para esto fue

 while running: for elem in li: thiselem = elem nextelem = li[li.index(elem)-len(li)+1] # negative index 

¿Hay una mejor manera de hacer esto?

Después de pensar esto detenidamente, creo que esta es la mejor manera. Te permite alejarte en el medio fácilmente sin usar break , lo que creo que es importante, y requiere un cálculo mínimo, por lo que creo que es el más rápido. Tampoco requiere que sea una lista o una tupla. Podría ser cualquier iterador.

 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) 

Dejo aquí las otras soluciones para la posteridad.

Todas esas cosas elegantes de iteradores tienen su lugar, pero no aquí. Utilice el operador%.

 li = [0, 1, 2, 3] running = True while running: for idx, elem in enumerate(li): thiselem = elem nextelem = li[(idx + 1) % len(li)] 

Ahora, si tiene la intención de recorrer una lista infinitamente, entonces haga esto:

 li = [0, 1, 2, 3] running = True idx = 0 while running: thiselem = li[idx] idx = (idx + 1) % len(li) nextelem = li[idx] 

Creo que es más fácil de entender que la otra solución que involucra tee , y probablemente también más rápido. Si está seguro de que la lista no cambiará de tamaño, puede guardar una copia de len(li) y usarla.

Esto también le permite alejarse fácilmente de la rueda de la fortuna en el medio en lugar de tener que esperar a que el cucharón descienda de nuevo al fondo. Las otras soluciones (incluida la suya) requieren que verifique la running en el medio del ciclo for y luego se break .

 while running: for elem,next_elem in zip(li, li[1:]+[li[0]]): ... 

Puedes usar un iterador cíclico de pares:

 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)): ... 

Usa el método zip en Python. Esta función devuelve una lista de tuplas, donde la i-th tupla contiene el elemento i-th de cada una de las secuencias de argumentos o iterables.

  while running: for thiselem,nextelem in zip(li, li[1 : ] + li[ : 1]): #Do whatever you want with thiselem and nextelem 
 while running: lenli = len(li) for i, elem in enumerate(li): thiselem = elem nextelem = li[(i+1)%lenli] 

Una forma bastante diferente de resolver esto:

  li = [0,1,2,3] for i in range(len(li)): if i < len(li)-1: # until end is reached print 'this', li[i] print 'next', li[i+1] else: # end print 'this', li[i] 
  li = [0, 1, 2, 3] for elem in li: if (li.index(elem))+1 != len(li): thiselem = elem nextelem = li[li.index(elem)+1] print 'thiselem',thiselem print 'nextel',nextelem else: print 'thiselem',li[li.index(elem)] print 'nextel',li[li.index(elem)] 
 c = [ 1, 2, 3, 4 ] i = int(raw_input(">")) if i < 4: print i + 1 else: print -1