2009-05-27 9 views
98

Je voudrais parcourir une liste en vérifiant chaque élément par rapport à celui qui le suit.Comment faire une boucle sur tout sauf le dernier élément d'une liste?

Existe-t-il un moyen de parcourir tous les éléments sauf le dernier en utilisant x dans y? Je préférerais le faire sans utiliser d'index si je peux.

Remarque

freespace a répondu à ma question réelle, ce qui est la raison pour laquelle j'ai accepté la réponse, mais SilentGhost a répondu à la question que j'aurais demandé.

Toutes mes excuses pour la confusion.

Répondre

196
for x in y[:-1] 

Si y est un générateur, le ne fonctionnera pas ci-dessus.

+0

Cela répond à ma question, merci, mais j'ai oublié de demander comment j'obtiendrais l'article après x. Est-ce possible? –

+0

Je crois qu'une instruction "else" vous permettra de gérer ce qui se passe après que la boucle n'oublie pas de mettre x au dernier élément. – nevets1219

+2

- 1 Je ne pense pas que cela réponde à la question. Ce n'est pas comparer chaque article avec le suivant. - odwl il ya 0 secondes – odwl

18

Si vous souhaitez obtenir tous les éléments de la séquence par paire, utilisez cette approche (la fonction par paire provient des exemples du module itertools).

from itertools import tee, izip, chain 

def pairwise(seq): 
    a,b = tee(seq) 
    b.next() 
    return izip(a,b) 

for current_item, next_item in pairwise(y): 
    if compare(current_item, next_item): 
     # do what you have to do 

Si vous devez comparer la dernière valeur à une valeur spéciale, la chaîne que la valeur à la fin

for current, next_item in pairwise(chain(y, [None])): 
+0

Veuillez noter que l'utilisation de next pour les ombres de noms de variables intégrées – SilentGhost

+0

Personnellement, cela ne me dérange pas d'ombrer les builtins moins utilisés lorsque la portée de la variable est petite et que le nom est bon pour la lisibilité. Néanmoins édité les noms de variables pour maintenir de bonnes pratiques de codage. –

4

si vous vouliez dire comparer nième élément avec n + 1 e élément dans la liste que vous pourriez faire aussi avec

>>> for i in range(len(list[:-1])): 
...  print list[i]>list[i+1] 

Notez qu'il n'y a pas de codage dur qui s'y passe. Cela devrait être bon, sauf si vous ressentez le contraire.

+2

Vous pouvez remplacer len (list [: - 1]) avec len (list) - 1 pour éviter une copie de liste. Et évitez d'utiliser une variable appelée liste ... –

37

la meilleure façon de comparer l'élément de séquence avec les éléments suivants:

for i, j in zip(a, a[1:]): 
    # compare i (the current) to j (the following) 
+9

Cela répond à la question que j'aurais souhaité poser. Merci –

+2

En fait, vous pouvez omettre la première tranche, puisque zip tronque la plus longue liste à la longueur de la plus courte. Cela vous permettra d'économiser une création de liste. (Au cas où vous auriez affaire à d'énormes listes, mais dans ce cas, vous devriez suivre l'approche d'Ants Aasma, qui ne copie rien.) – bayer

+0

merci, généralement inutile, il semble en effet plus propre. – SilentGhost

0

Pour comparer chaque élément avec la suivante dans un itérateur sans instancier une liste:

import itertools 
it = (x for x in range(10)) 
data1, data2 = itertools.tee(it) 
data2.next() 
for a, b in itertools.izip(data1, data2): 
    print a, b 
+1

c'est exactement ce qui a été suggéré par Ants Aasma http://stackoverflow.com/questions/914715/python-looping-through-all-but-the-last-item-of-a-list/914786#914786 – SilentGhost

0

Cela répond à ce que le OP aurait dû demander, soit parcourir une liste en comparant les éléments consécutifs (excellente réponse SilentGhost), mais généralisée pour tout groupe (n-gram): 2, 3, ... n:

zip(*(l[start:] for start in range(0, n)))

Exemples:

l = range(0, 4) # [0, 1, 2, 3] 

list(zip(*(l[start:] for start in range(0, 2)))) # == [(0, 1), (1, 2), (2, 3)] 
list(zip(*(l[start:] for start in range(0, 3)))) # == [(0, 1, 2), (1, 2, 3)] 
list(zip(*(l[start:] for start in range(0, 4)))) # == [(0, 1, 2, 3)] 
list(zip(*(l[start:] for start in range(0, 5)))) # == [] 

Explications:

  • l[start:] génère aa liste/générateur à partir de l'index start
  • *list ou *generator: passe tous elem ents à la fonction englobante zip comme il a été écrit zip(elem1, elem2, ...)

Note:

AFAIK, ce code est aussi paresseux que possible. Pas testé.

Questions connexes