Question

I have a loop condition:

for count, item in enumerate(contents):

but only want to use the first 10 elements of contents. What is the most pythonic way to do so?

Doing a:

if count == 10: break

seems somewhat un-Pythonic. Is there a better way?

Was it helpful?

Solution

Use a slice (slice notation)

for count, item in enumerate(contents[:10]):

If you are iterating over a generator, or the items in your list are large and you don't want the overhead of creating a new list (as slicing does) you can use islice from the itertools module:

for count, item in enumerate(itertools.islice(contents, 10)):

Either way, I suggest you do this in a robust manner, which means wrapping the functionality inside a function (as one is want to do with such functionality - indeed, it is the reason for the name function)

import itertools

def enum_iter_slice(collection, slice):
    return enumerate(itertools.islice(collection, slice))

Example:

>>> enum_iter_slice(xrange(100), 10)
<enumerate object at 0x00000000025595A0>
>>> list(enum_iter_slice(xrange(100), 10))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]
>>> for idx, item in enum_iter_slice(xrange(100), 10):
    print idx, item

0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9

If you were using enumerate and your count variable just to check the items index (so that using your method you could exit/break the loop on the 10th item.) You don't need enumerate, and just use the itertools.islice() all on its own as your function.

for item in itertools.islice(contents, 10):

OTHER TIPS

If the list is large or contents is a generator, use itertools.islice():

from itertools import islice

for count, item in enumerate(islice(contents, 10)):

For smaller lists or tuples, just use slicing:

for count, item in enumerate(contents[:10]):

Slicing creates a new list or tuple object, which for 10 items is not that big a deal.

Just an addendum to the two answers already given:

I propose to think about the situation you are in. Why is is that you want to do 10 iterations and no more? Is it more the wish to abort after ten cycles (e. g. because each cycle takes up a long time and the whole runtime shall be limited while giving up completeness) or is the reason behind your requirement that the first ten elements are a special group of items (maybe the ten to display)?

In the first case I'd say the most correct way would actually be the if ... break you proposed because it represents your thoughts most direct.

In the latter case I'd propose to name the child, i. e. introduce a speaking name for that special group of the first ten elements (e. g. elements_to_display) and iterate over them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top