2012-07-16 3 views
3

J'ai une boucle qui est l'analyse des lignes d'un fichier texte:Effectuer une opération au cours de la dernière itération d'une boucle en python

for line in file: 
    if line.startswith('TK'): 
     for item in line.split(): 
      if item.startwith('ID='): 
       *stuff* 
      if last_iteration_of_loop 
       *stuff* 

je dois faire quelques travaux, mais je ne peux pas les faire jusqu'à ce que la dernière itération de la seconde pour la boucle. Y at-il un moyen de détecter cela, ou un moyen de savoir si im au dernier article de line.split()? Comme une note, les item s dans la deuxième boucle sont des chaînes, et I le contenu d'entre eux sont inconnus à l'exécution, donc je ne peux pas chercher une chaîne spécifique comme drapeau pour me faire savoir im à la fin.

Merci!

Répondre

8

Il suffit de se référer à la dernière ligne en dehors de la boucle:

for line in file: 
    if line.startswith('TK'): 
     item = None 
     for item in line.split(): 
      if item.startwith('ID='): 
       # *stuff* 

     if item is not None: 
      # *stuff* 

La variable item est toujours disponible en dehors de la boucle:

>>> for i in range(5): 
...  print i 
... 
0 
1 
2 
3 
4 
>>> print 'last:', i 
last: 4 

Notez que si votre fichier est vide (pas d'itérations dans la boucle) item ne sera pas défini; c'est pourquoi nous avons mis item = None avant la boucle et testons ensuite if item is not None.

Si vous devez avoir le dernier élément qui correspondent à votre test, stocker que dans une nouvelle variable:

for line in file: 
    if line.startswith('TK'): 
     lastitem = None 
     for item in line.split(): 
      if item.startwith('ID='): 
       lastitem = item 
       # *stuff* 

     if lastitem is not None: 
      # *stuff* 

Démonstration de la deuxième option:

>>> lasti = None 
>>> for i in range(5): 
...  if i % 2 == 0: 
...   lasti = i 
... 
>>> lasti 
4 
+4

'else' à une boucle' for' est complètement inutile sans une déclaration 'break' dans la boucle. –

+1

Normalement, je suis d'accord avec cette approche (d'accord avec @SvenMarnach). Mais que faire si l'OP doit faire quelque chose à '4' avant de l'imprimer? Cela ne marcherait pas très bien dans cette construction – inspectorG4dget

+0

Je ne pense pas que cela documente quoi que ce soit. Même l'utilisation idiomatique de 'for' /' else' déroute les gens, mais c'est vraiment déroutant. –

1

Essayez ceci:

for line in file: 
    if line.startswith('TK'): 
     items = line.split() 
     num_loops = len(items) 
     for i in range len(items): 
      item = items[i] 
      if item.startwith('ID='): 
       *stuff* 
      if i==num_loops-1: # if last_iteration_of_loop 
       *stuff* 

Hope qui aide

0

Je ne sais pas pourquoi vous pouvez Il ne suffit pas de modifier en dehors de la boucle finale, mais vous pourrez peut-être faire usage de ceci - qui fonctionne avec n'importe quel itérateur, pas seulement ceux de longueur connue ...

pas largement testé et peut-être pas efficace

from itertools import tee, izip_longest, count 

def something(iterable): 
    sentinel = object() 
    next_count = count(1) 

    iterable = iter(iterable) 
    try: 
     first = next(iterable) 
    except StopIteration: 
     yield sentinel, 'E', 0 # empty 

    yield first, 'F', next(next_count) # first 

    fst, snd = tee(iterable) 
    next(snd) 
    for one, two in izip_longest(fst, snd, fillvalue=sentinel): 
     yield one, 'L' if two is sentinel else 'B', next(next_count) # 'L' = last, 'B' = body 
Questions connexes