Question

Ss there a simple way to iterate over an iterable object that allows the specification of an end point, say -1, as well as the start point in enumerate. e.g.

for i, row in enumerate(myiterable, start=2): # will start indexing at 2

So if my object has a length of 10, what is the simplest way to to get it to start iterating at index 2 and stop iterating at index 9?

Alternatively, is there something from itertools that is more suitable for this. I am specifically interested in high performance methods.

In addition, when the start option was introduced in 2.6, is there any reason why a stop option was not?

Cheers

Was it helpful?

Solution

for i, row in enumerate(myiterable[2:], start=2):
   if i>= limit: break
   ...

or

for i,row in itertools.takewhile(lambda (i,val):i < limit,enumerate(myiterable[2:],2)):

to rephrase the other suggestion (note that it will only work if your iterable is a sliceable object)

start,stop = 11,20
my_items = range(100)
for i,row in enumerate(my_items[start:stop],start):
      ....

OTHER TIPS

I think you've misunderstood the 'start' keyword, it doesn't skip to the nth item in the iterable, it starts counting at n, for example:

for i, c in enumerate(['a', 'b', 'c'], start=5):
    print i, c

gives:

5 a
6 b
7 c

For simple iterables like lists and tuples the simplest and fastest method is going to be something like:

obj = range(100)
start = 11
stop = 22
for i, item in enumerate(obj[start:stop], start=start):
    pass

If I'm not going to be using the whole length of the iterable item, I find it easier to use something like:

for i in range(2, len(myiterable)):

instead of enumerate. And then index based on i within the loop. It requires less typing than other approaches that use enumerate.

Creating the slice of an iterable object could be expensive. To avoid this, use itertools.islice:

import itertools

for item in itertools.islice('abc', 0, 2):
  print(item)

# will print:
1
2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top