167 lines
4.8 KiB
Plaintext
167 lines
4.8 KiB
Plaintext
PEP: 212
|
||
Title: Loop Counter Iteration
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: nowonder@nowonder.de (Peter Schneider-Kamp)
|
||
Status: Draft
|
||
Type: Standards Track
|
||
Created: 22-Aug-2000
|
||
Python-Version: 2.1
|
||
|
||
|
||
Introduction
|
||
|
||
This PEP describes the often proposed feature of exposing the loop
|
||
counter in for-loops. This PEP tracks the status and ownership of
|
||
this feature. It contains a description of the feature and
|
||
outlines changes necessary to support the feature. This PEP
|
||
summarizes discussions held in mailing list forums, and provides
|
||
URLs for further information, where appropriate. The CVS revision
|
||
history of this file contains the definitive historical record.
|
||
|
||
|
||
Motivation
|
||
|
||
Standard for-loops in Python iterate over the elements of a
|
||
sequence[1]. Often it is desirable to loop over the indices or
|
||
both the elements and the indices instead.
|
||
|
||
The common idioms used to accomplish this are unintuitive. This
|
||
PEP proposes two different ways of exposing the indices.
|
||
|
||
|
||
Loop counter iteration
|
||
|
||
The current idiom for looping over the indices makes use of the
|
||
built-in 'range' function:
|
||
|
||
for i in range(len(sequence)):
|
||
# work with index i
|
||
|
||
Looping over both elements and indices can be achieved either by the
|
||
old idiom or by using the new 'zip' built-in function[2]:
|
||
|
||
for i in range(len(sequence)):
|
||
e = sequence[i]
|
||
# work with index i and element e
|
||
|
||
or
|
||
|
||
for i, e in zip(range(len(sequence)), sequence):
|
||
# work with index i and element e
|
||
|
||
|
||
The Proposed Solutions
|
||
|
||
There are three solutions that have been discussed. One adds a
|
||
non-reserved keyword, the other adds two built-in functions.
|
||
A third solution adds methods to sequence objects.
|
||
|
||
|
||
Non-reserved keyword 'indexing'
|
||
|
||
This solution would extend the syntax of the for-loop by adding
|
||
an optional '<variable> indexing' clause which can also be used
|
||
instead of the '<variable> in' clause..
|
||
|
||
Looping over the indices of a sequence would thus become:
|
||
|
||
for i indexing sequence:
|
||
# work with index i
|
||
|
||
Looping over both indices and elements would similarly be:
|
||
|
||
for i indexing e in sequence:
|
||
# work with index i and element e
|
||
|
||
|
||
Built-in functions 'indices' and 'irange'
|
||
|
||
This solution adds two built-in functions 'indices' and 'irange'.
|
||
The semantics of these can be described as follows:
|
||
|
||
def indices(sequence):
|
||
return range(len(sequence))
|
||
|
||
def irange(sequence):
|
||
return zip(range(len(sequence)), sequence)
|
||
|
||
These functions could be implemented either eagerly or lazily and
|
||
should be easy to extend in order to accept more than one sequence
|
||
argument.
|
||
|
||
The use of these functions would simplify the idioms for looping
|
||
over the indices and over both elements and indices:
|
||
|
||
for i in indices(sequence):
|
||
# work with index i
|
||
|
||
for i, e in irange(sequence):
|
||
# work with index i and element e
|
||
|
||
|
||
Methods for sequence objects
|
||
|
||
This solution proposes the addition of 'indices', 'items'
|
||
and 'values' methods to sequences, which enable looping over
|
||
indices only, both indices and elements, and elements only
|
||
respectively.
|
||
|
||
This would immensely simplify the idioms for looping over indices
|
||
and for looping over both elements and indices:
|
||
|
||
for i in sequence.indices():
|
||
# work with index i
|
||
|
||
for i, e in sequence.items():
|
||
# work with index i and element e
|
||
|
||
Additionally it would allow to do looping over the elements
|
||
of sequences and dicitionaries in a consistent way:
|
||
|
||
for e in sequence_or_dict.values():
|
||
# do something with element e
|
||
|
||
|
||
Implementations
|
||
|
||
For all three solutions some more or less rough patches exist
|
||
as patches at SourceForge:
|
||
|
||
'for i indexing a in l': exposing the for-loop counter[3]
|
||
add indices() and irange() to built-ins[4]
|
||
add items() method to listobject[5]
|
||
|
||
All of them have been pronounced on and rejected by the BDFL.
|
||
|
||
Note that the 'indexing' keyword is only a NAME in the
|
||
grammar and so does not hinder the general use of 'indexing'.
|
||
|
||
|
||
Backward Compatibility Issues
|
||
|
||
As no keywords are added and the semantics of existing code
|
||
remains unchanged, all three solutions can be implemented
|
||
without breaking existing code.
|
||
|
||
|
||
Copyright
|
||
|
||
This document has been placed in the public domain.
|
||
|
||
|
||
References
|
||
|
||
[1] http://www.python.org/doc/current/ref/for.html
|
||
[2] Lockstep Iteration, PEP 201
|
||
[3] http://sourceforge.net/patch/download.php?id=101138
|
||
[4] http://sourceforge.net/patch/download.php?id=101129
|
||
[5] http://sourceforge.net/patch/download.php?id=101178
|
||
|
||
|
||
|
||
Local Variables:
|
||
mode: indented-text
|
||
indent-tabs-mode: nil
|
||
End:
|