I want to iterate over everything in a list except the first few elements, e.g.:
for line in lines[2:]:
foo(line)
This is concise, but
The original solution is, in most cases, the appropriate one.
for line in lines[2:]:
foo(line)
While this does copy the list, it is only a shallow copy, and is quite quick. Don't worry about optimizing until you have profiled the code and found this to be a bottleneck.
You can try itertools.islice(iterable[, start], stop[, step]):
import itertools
for line in itertools.islice(list , start, stop):
foo(line)
Although itertools.islice
appears to be the optimal solution for this problem, somehow, the extra import just seems like overkill for something so simple.
Personally, I find the enumerate
solution perfectly readable and succinct - although I would prefer to write it like this:
for index, line in enumerate(lines):
if index >= 2:
foo(line)
I prefer to use dropwhile for this. It feels natural after using it in Haskell and some other languages, and seems reasonably clear. You can also use it in many other cases where you want to look for a "trigger" condition more complex than the item's index for the start of the iteration.
from itertools import dropwhile
for item in dropwhile(lambda x: x[0] < 2, enumerate(lst)):
# ... do something with item
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
Now you can for i in skip_heading( lines, 2 ):
without worrying.
for fooable in (line for i,line in enumerate(lines) if i >= 2):
foo(fooable)