PEP 279 – The enumerate() built-in function | peps.python.org (2024)

Author:
Raymond Hettinger <python at rcn.com>
Status:
Final
Type:
Standards Track
Created:
30-Jan-2002
Python-Version:
2.3
Post-History:
Table of Contents
  • Abstract
  • Rationale
  • BDFL Pronouncements
  • Specification for a new built-in
  • Copyright

Abstract

This PEP introduces a new built-in function, enumerate() tosimplify a commonly used looping idiom. It provides all iterablecollections with the same advantage that iteritems() affords todictionaries – a compact, readable, reliable index notation.

Rationale

Python 2.2 introduced the concept of an iterable interface asproposed in PEP 234. The iter() factory function was providedas common calling convention and deep changes were made to useiterators as a unifying theme throughout Python. The unificationcame in the form of establishing a common iterable interface formappings, sequences, and file objects.

Generators, as proposed in PEP 255, were introduced as a meansfor making it easier to create iterators, especially ones withcomplex internal execution or variable states. The availabilityof generators makes it possible to improve on the loop counterideas in PEP 212. Those ideas provided a clean syntax foriteration with indices and values, but did not apply to alliterable objects. Also, that approach did not have the memoryfriendly benefit provided by generators which do not evaluate theentire sequence all at once.

The new proposal is to add a built-in function, enumerate() whichwas made possible once iterators and generators became available.It provides all iterables with the same advantage that iteritems()affords to dictionaries – a compact, readable, reliable indexnotation. Like zip(), it is expected to become a commonly usedlooping idiom.

This suggestion is designed to take advantage of the existingimplementation and require little additional effort toincorporate. It is backwards compatible and requires no newkeywords. The proposal will go into Python 2.3 when generatorsbecome final and are not imported from __future__.

BDFL Pronouncements

The new built-in function is ACCEPTED.

Specification for a new built-in

def enumerate(collection): 'Generates an indexed series: (0,coll[0]), (1,coll[1]) ...' i = 0 it = iter(collection) while 1: yield (i, it.next()) i += 1

Note A: PEP 212 Loop Counter Iteration discussed severalproposals for achieving indexing. Some of the proposals only workfor lists unlike the above function which works for any generator,xrange, sequence, or iterable object. Also, those proposals werepresented and evaluated in the world prior to Python 2.2 which didnot include generators. As a result, the non-generator version inPEP 212 had the disadvantage of consuming memory with a giant listof tuples. The generator version presented here is fast andlight, works with all iterables, and allows users to abandon thesequence in mid-stream with no loss of computation effort.

There are other PEPs which touch on related issues: integeriterators, integer for-loops, and one for modifying the argumentsto range and xrange. The enumerate() proposal does not precludethe other proposals and it still meets an important need even ifthose are adopted – the need to count items in any iterable. Theother proposals give a means of producing an index but not thecorresponding value. This is especially problematic if a sequenceis given which doesn’t support random access such as a fileobject, generator, or sequence defined with __getitem__.

Note B: Almost all of the PEP reviewers welcomed the function butwere divided as to whether there should be any built-ins. Themain argument for a separate module was to slow the rate oflanguage inflation. The main argument for a built-in was that thefunction is destined to be part of a core programming style,applicable to any object with an iterable interface. Just aszip() solves the problem of looping over multiple sequences, theenumerate() function solves the loop counter problem.

If only one built-in is allowed, then enumerate() is the mostimportant general purpose tool, solving the broadest class ofproblems while improving program brevity, clarity and reliability.

Note C: Various alternative names were discussed:

iterindexed()five syllables is a mouthful
index()nice verb but could be confused the .index() method
indexed()widely liked however adjectives should be avoided
indexer()noun did not read well in a for-loop
count()direct and explicit but often used in other contexts
itercount()direct, explicit and hated by more than one person
iteritems()conflicts with key:value concept for dictionaries
itemize()confusing because amap.items() != list(itemize(amap))
enum()pithy; less clear than enumerate; too similar to enumin other languages where it has a different meaning

All of the names involving ‘count’ had the further disadvantage ofimplying that the count would begin from one instead of zero.

All of the names involving ‘index’ clashed with usage in databaselanguages where indexing implies a sorting operation rather thanlinear sequencing.

Note D: This function was originally proposed with optional startand stop arguments. GvR pointed out that the function callenumerate(seqn,4,6) had an alternate, plausible interpretation asa slice that would return the fourth and fifth elements of thesequence. To avoid the ambiguity, the optional arguments weredropped even though it meant losing flexibility as a loop counter.That flexibility was most important for the common case ofcounting from one, as in:

for linenum, line in enumerate(source,1): print linenum, line
Comments from GvR:
filter and map should die and be subsumed into listcomprehensions, not grow more variants. I’d rather introducebuilt-ins that do iterator algebra (e.g. the iterzip that I’veoften used as an example).

I like the idea of having some way to iterate over a sequenceand its index set in parallel. It’s fine for this to be abuilt-in.

I don’t like the name “indexed”; adjectives do not make goodfunction names. Maybe iterindexed()?

Comments from Ka-Ping Yee:
I’m also quite happy with everything youproposed … and the extra built-ins (really ‘indexed’ inparticular) are things I have wanted for a long time.
Comments from Neil Schemenauer:
The new built-ins sound okay. Guidomay be concerned with increasing the number of built-ins toomuch. You might be better off selling them as part of amodule. If you use a module then you can add lots of usefulfunctions (Haskell has lots of them that we could steal).
Comments for Magnus Lie Hetland:
I think indexed would be a useful andnatural built-in function. I would certainly use it a lot. Ilike indexed() a lot; +1. I’m quite happy to have it make PEP281 obsolete. Adding a separate module for iterator utilitiesseems like a good idea.
Comments from the Community:
The response to the enumerate() proposalhas been close to 100% favorable. Almost everyone loves theidea.
Author response:
Prior to these comments, four built-ins were proposed.After the comments, xmap, xfilter and xzip were withdrawn. Theone that remains is vital for the language and is proposed byitself. Indexed() is trivially easy to implement and can bedocumented in minutes. More importantly, it is useful ineveryday programming which does not otherwise involve explicituse of generators.

This proposal originally included another function iterzip().That was subsequently implemented as the izip() function inthe itertools module.

Copyright

This document has been placed in the public domain.

PEP 279 – The enumerate() built-in function | peps.python.org (2024)

References

Top Articles
Latest Posts
Article information

Author: Edmund Hettinger DC

Last Updated:

Views: 6236

Rating: 4.8 / 5 (78 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Edmund Hettinger DC

Birthday: 1994-08-17

Address: 2033 Gerhold Pine, Port Jocelyn, VA 12101-5654

Phone: +8524399971620

Job: Central Manufacturing Supervisor

Hobby: Jogging, Metalworking, Tai chi, Shopping, Puzzles, Rock climbing, Crocheting

Introduction: My name is Edmund Hettinger DC, I am a adventurous, colorful, gifted, determined, precious, open, colorful person who loves writing and wants to share my knowledge and understanding with you.