Often times when you are looping over a collection of items in Python you also need to have an ordinal number associated with each item.
Such a number is usually referred to as the
The pythonic way of accessing the index while doing a
foreach-loop is to use the built-in function
enumerate() adds an index to each item in an iterable collection.
You then can use the
list() builtin function to get back a list of tuples.
>>> names = ['Bob', 'Alice', 'John', 'Cindy'] >>> list(enumerate(names)) [(0, 'Bob'), (1, 'Alice'), (2, 'John'), (3, 'Cindy')]
Note, that usually indexing starts from
0 in Python.
However, if you want to start indexing from
1 (for example, when printing a report data), it’s trivially achieved by passing an additional
start argument to
>>> names = ['Bob', 'Alice', 'John', 'Cindy'] >>> list(enumerate(names), start=1) [(1, 'Bob'), (2, 'Alice'), (3, 'John'), (4, 'Cindy')]
The above approach is also useful if you’re printing data from different data sources but want to have a consistent index across all data items.
>>> data_source1 = ['Bob', 'Alice', 'John', 'Cindy'] >>> data_source2 = ['Sarah', 'Jeff', 'Emily', 'Adam'] >>> list(enumerate(data_source1, start=1)) [(1, 'Bob'), (2, 'Alice'), (3, 'John'), (4, 'Cindy')] >>> list(enumerate(data_source2, start=len(data_source1) + 1)) [(5, 'Sarah'), (6, 'Jeff'), (7, 'Emily'), (8, 'Adam')]
Note, that you don’t have to convert an
Enumerate object to a list.
It is an iterable itself so can iterate over it directly.
>>> names = ['Bob', 'Alice', 'John', 'Cindy'] >>> for idx, name in enumerate(names): ... print(name) ... Bob Alice John Cindy
There may be other ways to get a hold of the index while iterating over a collection of items,
enumerate() is considered canonical and is preferred.
Another option would be to use a separate index variable, initialize it manually and increment it manually at each iteration. Such an approach, however, would be considered to be a reinvention of the wheel and frowned upon.
Here is a quote from PEP 279 in which
enumerate() function was introduced.
This PEP introduces a new built-in function, enumerate() to simplify a commonly used looping idiom. It provides all iterable collections with the same advantage that iteritems() affords to dictionaries – a compact, readable, reliable index notation.
You may ask if there are any performance implications of using
enumerate in your code.
Well, you are free to do all the measurements, but please, keep in mind, that
enumerate is an idiomatic way to access an index of an iterable in a
Idiomatic code is recommended by the Python maintainers and they will make everything to
make it run efficiently.
And for those of you, who are most curious below is a possible implementation of
enumerate() function from the above PEP.
def enumerate(collection): 'Generates an indexed series: (0,coll), (1,coll) ...' i = 0 it = iter(collection) while 1: yield (i, it.next()) i += 1