diagrama caja bigote python

bigote - diagrama de caja python



forma pitónica para iterar sobre parte de una lista (7)

Aunque itertools.islice parece ser la solución óptima para este problema, de alguna manera, la importación adicional parece demasiado excesiva para algo tan simple.

Personalmente, considero que la solución enumerate perfectamente legible y sucinta, aunque preferiría escribirla así:

for index, line in enumerate(lines): if index >= 2: foo(line)

Quiero iterar sobre todo en una lista, excepto los primeros elementos, por ejemplo:

for line in lines[2:]: foo(line)

Esto es conciso, pero copia toda la lista, lo cual es innecesario. Yo podría hacer:

del lines[0:2] for line in lines: foo(line)

Pero esto modifica la lista, que no siempre es buena.

Puedo hacer esto:

for i in xrange(2, len(lines)): line = lines[i] foo(line)

Pero, eso es simplemente asqueroso.

Mejor podría ser esto:

for i,line in enumerate(lines): if i < 2: continue foo(line)

Pero no es tan obvio como el primer ejemplo.

Entonces, ¿cuál es la manera de hacerlo que es tan obvio como el primer ejemplo, pero no copia la lista innecesariamente?


La solución original es, en la mayoría de los casos, la adecuada.

for line in lines[2:]: foo(line)

Si bien esto copia la lista, es solo una copia superficial, y es bastante rápida. No se preocupe por la optimización hasta que haya perfilado el código y haya encontrado que se trata de un cuello de botella.


Prefiero usar dropwhile para esto. Se siente natural después de usarlo en Haskell y en otros idiomas, y parece razonablemente claro. También puede usarlo en muchos otros casos en los que desee buscar una condición de "desencadenante" más compleja que el índice del elemento para el inicio de la iteración.

from itertools import dropwhile for item in dropwhile(lambda x: x[0] < 2, enumerate(lst)): # ... do something with item


Puede construir un generador auxiliar:

def rangeit(lst, rng): for i in rng: yield lst[i] for e in rangeit(["A","B","C","D","E","F"], range(2,4)): print(e)



def skip_heading( iterable, items ): the_iter= iter( iterable ): for i, e in enumerate(the_iter): if i == items: break for e in the_iter: yield e

Ahora puede hacer for i in skip_heading( lines, 2 ): sin preocuparse.


for fooable in (line for i,line in enumerate(lines) if i >= 2): foo(fooable)