Les solutions jusqu'à présent ne concernent que les listes, et la plupart copient la liste. D'après mon expérience, ce n'est souvent pas possible.
En outre, ils ne traitent pas du fait que vous pouvez avoir des éléments répétés dans la liste.
Le titre de votre question dit " Valeurs précédentes et suivantes dans une boucle ", mais si vous exécutez la plupart des réponses ici dans une boucle, vous finirez par parcourir à nouveau la liste entière sur chaque élément pour le trouver.
Donc je viens de créer une fonction qui. en utilisant le itertoolsmodule, divise et tranche l'itérable, et génère des tuples avec les éléments précédent et suivant ensemble. Ce n'est pas exactement ce que fait votre code, mais cela vaut la peine d'y jeter un coup d'œil, car il peut probablement résoudre votre problème.
from itertools import tee, islice, chain, izip
def previous_and_next(some_iterable):
prevs, items, nexts = tee(some_iterable, 3)
prevs = chain([None], prevs)
nexts = chain(islice(nexts, 1, None), [None])
return izip(prevs, items, nexts)
Ensuite, utilisez-le dans une boucle, et vous aurez les éléments précédents et suivants:
mylist = ['banana', 'orange', 'apple', 'kiwi', 'tomato']
for previous, item, nxt in previous_and_next(mylist):
print "Item is now", item, "next is", nxt, "previous is", previous
Les resultats:
Item is now banana next is orange previous is None
Item is now orange next is apple previous is banana
Item is now apple next is kiwi previous is orange
Item is now kiwi next is tomato previous is apple
Item is now tomato next is None previous is kiwi
Cela fonctionnera avec n'importe quelle liste de taille (car il ne copie pas la liste), et avec n'importe quel itérable (fichiers, ensembles, etc.). De cette façon, vous pouvez simplement parcourir la séquence et avoir les éléments précédents et suivants disponibles dans la boucle. Pas besoin de rechercher à nouveau l'élément dans la séquence.
Une brève explication du code:
tee est utilisé pour créer efficacement 3 itérateurs indépendants sur la séquence d'entrée
chainrelie deux séquences en une seule; il est utilisé ici pour ajouter une séquence à un seul élément[None] à àprevs
islice est utilisé pour faire une séquence de tous les éléments sauf le premier, puis chain est utilisé pour ajouter unNone à sa fin
- Il y a maintenant 3 séquences indépendantes basées sur
some_iterable qui ressemblent à:
prevs: None, A, B, C, D, E
items: A, B, C, D, E
nexts: B, C, D, E, None
- enfin
izip est utilisé pour changer 3 séquences en une séquence de triplets.
Notez que izips'arrête quand une séquence d'entrée est épuisée, donc le dernier élément de prevssera ignoré, ce qui est correct - il n'y a pas d'élément tel que le dernier élément serait le sien prev. Nous pourrions essayer de supprimer les derniers éléments de prevsmaisizip le comportement de ce dernier rend cela redondant
Notez également que tee, izip, isliceetchain venir du itertoolsmodule; ils opèrent sur leurs séquences d'entrée à la volée (paresseusement), ce qui les rend efficaces et n'introduit pas le besoin d'avoir toute la séquence en mémoire à la fois à tout moment.
Dans python 3, il affichera une erreur lors de l'importation izip, vous pouvez utiliser à la zipplace de izip. Pas besoin d'importer zip, il est prédéfini dans python 3- source