51 votes

Comment accéder à l'élément précédent/suivant dans une boucle for ?

Existe-t-il un moyen d'accéder à un list (ou tuple de l'élément suivant ou précédent de l'itérable (ou d'un autre itérable) tout en le parcourant en boucle à l'aide d'une balise for boucle ?

l = [1, 2, 3]
for item in l:
    if item == 2:
        get_previous(l, item)

78voto

Markus Jarderot Points 33893

Exprimé comme une fonction de générateur :

def neighborhood(iterable):
    iterator = iter(iterable)
    prev_item = None
    current_item = next(iterator)  # throws StopIteration if empty.
    for next_item in iterator:
        yield (prev_item, current_item, next_item)
        prev_item = current_item
        current_item = next_item
    yield (prev_item, current_item, None)

Utilisation :

for prev,item,next in neighborhood(l):
    print prev, item, next

1 votes

Je pourrais faire "prev, item = item, next" dans ce cas.

1 votes

Pour faire ce cycle à l'infini (sans StopIteration), faites from itertools import cycle et changez la deuxième ligne en : iterator = cycle(iterable)

0 votes

Est-il moins pythique d'utiliser enumerate dans ce contexte ?

35voto

Vicky Points 59
l = [1, 2, 3]

for i, j in zip(l, l[1:]):
    print(i, j)

14 votes

J'ai utilisé ceci, mais j'ai élargi pour éviter de laisser tomber les éléments de début et de fin : for prev,cur,next in zip([None]+l[:-1], l, l[1:]+[None]):

0 votes

Vous pouvez éviter de laisser tomber les éléments de début et de fin comme ceci : l = [None, *l, None] et ensuite for prev, cur, nxt in zip(l, l[1:], l[2:]):

12voto

Rudiger Wolf Points 1053
l = [1, 2, 3]
for i, item in enumerate(l):
    if item == 2:
        previous = l[i - 1]
        print(previous)

Sortie :

1

Cette commande retournera le dernier élément de la liste si l'élément que vous recherchez est le premier élément de la liste. En d'autres termes, en changeant la troisième ligne en if item == 1: dans le code ci-dessus entraînera l'impression de 3 .

0 votes

Si votre liste ne comporte qu'un seul élément l = [2] ce qui renvoie le même élément que l'élément précédent.

10voto

Brian Points 48423

Lorsque je traite des générateurs pour lesquels vous avez besoin d'un certain contexte, j'utilise souvent la fonction utilitaire ci-dessous pour donner une vue en fenêtre glissante sur un itérateur :

import collections, itertools

def window(it, winsize, step=1):
    """Sliding window iterator."""
    it=iter(it)  # Ensure we have an iterator
    l=collections.deque(itertools.islice(it, winsize))
    while 1:  # Continue till StopIteration gets raised.
        yield tuple(l)
        for i in range(step):
            l.append(it.next())
            l.popleft()

Il générera une vue de la séquence de N éléments à la fois, en décalant les étapes. par exemple.

>>> list(window([1,2,3,4,5],3))
[(1, 2, 3), (2, 3, 4), (3, 4, 5)]

Dans les situations de lookahead/behind où vous devez également traiter des nombres sans valeur suivante ou précédente, vous pouvez compléter la séquence avec une valeur appropriée telle que None.

l= range(10)
# Print adjacent numbers
for cur, next in window(l + [None] ,2):
    if next is None: print "%d is the last number." % cur
    else: print "%d is followed by %d" % (cur,next)

0 votes

Si vous utilisez itertools , utilisez la réponse de Francisco Couzo avec itertools.tee à la place : stackoverflow.com/a/41047005

5voto

codeape Points 38576

Découvrez l'utilitaire looper de la Projet Tempita . Il vous donne un objet enveloppant autour de l'élément de la boucle qui fournit des propriétés telles que précédent, suivant, premier, dernier, etc.

Jetez un coup d'œil à la code source pour la classe looper, c'est assez simple. Il existe d'autres aides de ce type pour les boucles, mais je ne m'en souviens pas pour l'instant.

Ejemplo:

> easy_install Tempita
> python
>>> from tempita import looper
>>> for loop, i in looper([1, 2, 3]):
...     print loop.previous, loop.item, loop.index, loop.next, loop.first, loop.last, loop.length, loop.odd, loop.even
... 
None 1 0 2 True False 3 True 0
1 2 1 3 False False 3 False 1
2 3 2 None False True 3 True 0

1 votes

Tous les liens sont cassés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X