2012-07-05 7 views
8

Estoy tratando de recorrer una lista, y necesito realizar la operación específica cuando y sólo cuando la iteración llega al final de la lista, consulte el ejemplo siguiente:iterar a través de la lista y manejar StopIteration en Python bellamente

data = [1, 2, 3] 

data_iter = data.__iter__() 
try: 
    while True: 
     item = data_iter.next() 
     try: 
      do_stuff(item) 
      break # we just need to do stuff with the first successful item 
     except: 
      handle_errors(item) # in case of no success, handle and skip to next item 
except StopIteration: 
    raise Exception("All items weren't successful") 

Creo que este código no es demasiado Pythonic, entonces estoy buscando una mejor manera. Creo que el código ideal debería parecerse a esta pieza hipotética a continuación:

data = [1, 2, 3] 

for item in data: 
    try: 
     do_stuff(item) 
     break # we just need to do stuff with the first successful item 
    except: 
     handle_errors(item) # in case of no success, handle and skip to next item 
finally: 
    raise Exception("All items weren't successful") 

Cualquier idea es bienvenida.

+0

reemplazar 'finally' con' else'? – WolframH

+0

¿Por qué tiene '' Todos los artículos no fueron exitosos'' en lugar de '" Todos los artículos no fueron exitosos "'? Ese apóstrofo medio romperá su cadena/excepción si se ejecuta. Además, para el punto de WolframH, vea [docs] (http://docs.python.org/reference/compound_stmts.html#for) - 'else' en lugar de' finally' debería funcionar. – thegrinner

+1

Vale la pena señalar que 'except:' es algo terrible, si es solo por ejemplo, está bien, pero en cualquier ejemplo real, solo capte una excepción específica. –

Respuesta

16

Puede utilizar else después de un bucle, y el código dentro de ese else sólo se ejecuta si no lo hizo break fuera del bucle for:

data = [1, 2, 3] 

for item in data: 
    try: 
     do_stuff(item) 
     break # we just need to do stuff with the first successful item 
    except Exception: 
     handle_errors(item) # in case of no success, handle and skip to next item 
else: 
    raise Exception("All items weren't successful") 

Usted puede encontrar esto en las documentation for the for statement, piezas relevantes muestra a continuación:

for_stmt ::= "for" target_list "in" expression_list ":" suite 
       ["else" ":" suite] 

a break instrucción ejecutada en la primera suite termina el bucle sin ejecutar laSuite de 210 cláusulas.

+1

Mientras lo escribía. +1 - esta es la mejor manera de hacerlo. –

+0

Sí, era obvio, ¡gracias! –

Cuestiones relacionadas