2010-09-06 20 views
5

yo soy un aficionado y me nido novato para los bucles cuando escribo pitón, de este modo:Python: bucles for anidados o "Next"

dict = { 
    key1: {subkey/value1: value2} 
    ... 
    keyn: {subkeyn/valuen: valuen+1} 
    } 

for key in dict: 
    for subkey/value in key: 
     do it to it 

yo sepa una palabra clave "siguiente" que lograría el mismo objetivo en una línea (hice una pregunta sobre cómo usarlo pero no lo entendí del todo).

Para mí, un bucle anidado es mucho más legible. ¿Por qué, entonces la gente usa "siguiente"? Leí en alguna parte que Python es un lenguaje interpretado de forma dinámica y porque + concontinates cadenas y números de sumas, que debe verificar los tipos de variables para cada iteración de bucle con el fin de saber qué son los operadores, etc. ¿Con el uso de "siguiente" prevenir esto de alguna manera, acelerar la ejecución o es solo una cuestión de estilo/preferencia?

Respuesta

20

next es valioso para avanzar en un iterador cuando sea necesario, sin que avance el control de un bucle explícito for. Por ejemplo, si quiere "el primer artículo en S que es mayor que 100", se lo dará next(x for x in S if x > 100), sin complicaciones, sin problemas, sin trabajo innecesario (ya que todo termina tan pronto como se encuentre un x adecuado) - y obtiene una excepción (StopIteration) si inesperadamente no x coincide con la condición. Si se espera una no coincidencia y desea None en ese caso, next((x for x in S if x > 100), None) lo entregará. Para este propósito específico, podría ser más claro para usted si next realmente se llamara first, pero eso traicionaría su uso mucho más general.

Considere, por ejemplo, la tarea de fusionar secuencias múltiples (por ejemplo, una unión o intersección de secuencias ordenadas, por ejemplo, archivos ordenados, donde los elementos son líneas). De nuevo, next es exactamente lo que ordenó el médico, porque ninguna de las secuencias puede dominar a las demás controlando A "principal for loop". Entonces, asumiendo por simplicidad que no pueden existir duplicados (una condición que no es difícil relajar si es necesario), mantienes los pares (currentitem, itsfile) en una lista controlada por heapq, y la fusión se vuelve fácil ... pero solo gracias a la magia de next para avanzar el archivo correcto una vez que se ha utilizado su elemento, y ese solo archivo.

import heapq 

def merge(*theopentextfiles): 
    theheap = [] 
    for afile in theopentextfiles: 
     theitem = next(afile, '') 
     if theitem: theheap.append((theitem, afile)) 
    heapq.heapify(theheap) 
    while theheap: 
     theitem, afile = heapq.heappop(theheap) 
     yielf theitem 
     theitem = next(afile, '') 
     if theitem: heapq.heappush(theheap, (theitem, afile)) 

Sólo tratar de hacer cualquier cosa en cualquier lugar de este elegante sin next ... -!)

Se podría continuar durante mucho tiempo, pero los dos casos de uso "avanzar en un iterador por un solo lugar (sin dejar que controle un ciclo completo de for) "y" obtener solo el primer elemento de un iterador "para los usos más importantes de next.

+0

+1 ¡Respuesta agradable! –

+0

@AJ, ¡gracias! –

+0

+1 Lo hiciste de nuevo. Me acabo de dar cuenta de que mi útil cualquier aka primero podría definirse (primero no falso en cualquier secuencia o último valor en secuencia si todos son falsos) podría definirse también con next y iter. –

Cuestiones relacionadas