li = [0, 1, 2, 3]
running = True
while running:
for elem in li:
thiselem = elem
nextelem = li[li.index(elem)+1]
Lorsque ceci atteint le dernier élément, une IndexError
est déclenchée (comme c'est le cas pour toute liste, tuple, dictionnaire ou chaîne itéré). À ce stade, je souhaite que nextelem
soit égal à li[0]
. Ma solution plutôt lourde à cela était
while running:
for elem in li:
thiselem = elem
nextelem = li[li.index(elem)-len(li)+1] # negative index
Existe-t-il une meilleure façon de le faire?
Après avoir bien réfléchi à cette question, je pense que c'est la meilleure solution. Il vous permet de vous déplacer facilement au milieu sans utiliser break
, ce qui me semble important, et nécessite un minimum de calcul, donc je pense que c'est le plus rapide. De plus, il n'est pas nécessaire que li
soit une liste ou un tuple. Ce pourrait être n'importe quel itérateur.
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)
Je laisse les autres solutions ici pour la postérité.
Tous ces trucs fantaisie d'itérateur ont leur place, mais pas ici. Utilisez l'opérateur%.
li = [0, 1, 2, 3]
running = True
while running:
for idx, elem in enumerate(li):
thiselem = elem
nextelem = li[(idx + 1) % len(li)]
Maintenant, si vous avez l’intention de parcourir une liste à l’infini, procédez comme suit:
li = [0, 1, 2, 3]
running = True
idx = 0
while running:
thiselem = li[idx]
idx = (idx + 1) % len(li)
nextelem = li[idx]
Je pense que c'est plus facile à comprendre que l'autre solution impliquant tee
, et probablement plus rapide aussi. Si vous êtes sûr que la liste ne changera pas de taille, vous pouvez récupérer une copie de len(li)
et l'utiliser.
Cela vous permet également de descendre facilement de la grande roue au milieu au lieu d'attendre que le seau redescende. Les autres solutions (y compris la vôtre) nécessitent que vous vérifiiez running
au milieu de la boucle for
, puis break
.
while running:
for elem,next_elem in Zip(li, li[1:]+[li[0]]):
...
Vous pouvez utiliser un itérateur cyclique par paires:
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)):
...
Utilisez la méthode Zip en Python. Cette fonction retourne une liste de n-uplets, où le i-ème tuple contient le i-ème élément de chacune des séquences d'arguments ou 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]
Une façon assez différente de résoudre ceci:
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)]