134 lines
3.8 KiB
Plaintext
134 lines
3.8 KiB
Plaintext
|
PEP: 281
|
|||
|
Title: Loop Counter Iteration with range and xrange
|
|||
|
Version: $Revision$
|
|||
|
Last-Modified: $Date$
|
|||
|
Author: magnus@hetland.org (Magnus Lie Hetland)
|
|||
|
Status: Draft
|
|||
|
Type: Standards Track
|
|||
|
Created: 11-Feb-2002
|
|||
|
Python-Version: 2.3
|
|||
|
|
|||
|
|
|||
|
Abstract
|
|||
|
|
|||
|
This PEP describes yet another way of exposing the loop counter in
|
|||
|
for-loops. It basically proposes that the functionality of the
|
|||
|
function indices() from PEP 212 [1] be included in the existing
|
|||
|
functions range() and xrange().
|
|||
|
|
|||
|
|
|||
|
Motivation
|
|||
|
|
|||
|
It is often desirable to loop over the indices of a sequence. PEP
|
|||
|
212 describes several ways of doing this, including adding a
|
|||
|
built-in function called indices, conceptually defined as
|
|||
|
|
|||
|
def indices(sequence):
|
|||
|
return range(len(sequence))
|
|||
|
|
|||
|
On the assumption that adding functionality to an existing built-in
|
|||
|
function may be less intrusive than adding a new built-in function,
|
|||
|
this PEP proposes adding this functionality to the existing
|
|||
|
functions range() and xrange().
|
|||
|
|
|||
|
|
|||
|
Specification
|
|||
|
|
|||
|
It is proposed that all three arguments to the built-in functions
|
|||
|
range() and xrange() are allowed to be objects with a length
|
|||
|
(i.e. objects implementing the __len__ method). If an argument
|
|||
|
cannot be interpreted as an integer (i.e. it has no __int__
|
|||
|
method), its length will be used instead.
|
|||
|
|
|||
|
Examples:
|
|||
|
|
|||
|
>>> range(range(10))
|
|||
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|||
|
>>> range(range(5), range(10))
|
|||
|
[5, 6, 7, 8, 9]
|
|||
|
>>> range(range(5), range(10), range(2))
|
|||
|
[5, 7, 9]
|
|||
|
>>> list(xrange(range(10)))
|
|||
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|||
|
>>> list(xrange(xrange(10)))
|
|||
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|||
|
|
|||
|
# Number the lines of a file:
|
|||
|
lines = file.readlines()
|
|||
|
for num in range(lines):
|
|||
|
print num, lines[num]
|
|||
|
|
|||
|
|
|||
|
Alternatives
|
|||
|
|
|||
|
A natural alternative to the above specification is allowing
|
|||
|
xrange() to access its arguments in a lazy manner. Thus, instead
|
|||
|
of using their length explicitly, xrange can return one index for
|
|||
|
each element of the stop argument until the end is reached. A
|
|||
|
similar lazy treatment makes little sense for the start and step
|
|||
|
arguments since their length must be calculated before iteration
|
|||
|
can begin. (Actually, the length of the step argument isn't needed
|
|||
|
until the second element is returned.)
|
|||
|
|
|||
|
A pseudo-implementation (using only the stop argument, and assuming
|
|||
|
that it is iterable) is:
|
|||
|
|
|||
|
def xrange(stop):
|
|||
|
i = 0
|
|||
|
for x in stop:
|
|||
|
yield i
|
|||
|
i += 1
|
|||
|
|
|||
|
Testing whether to use int() or lazy iteration could be done by
|
|||
|
checking for an __iter__ attribute. (This example assumes the
|
|||
|
presence of generators, but could easily have been implemented as a
|
|||
|
plain iterator object.)
|
|||
|
|
|||
|
It may be questionable whether this feature is truly useful, since
|
|||
|
one would not be able to access the elements of the iterable object
|
|||
|
inside the for loop through indexing.
|
|||
|
|
|||
|
Example:
|
|||
|
|
|||
|
# Printing the numbers of the lines of a file:
|
|||
|
for num in range(file):
|
|||
|
print num # The line itself is not accessible
|
|||
|
|
|||
|
A more controversial alternative (to deal with this) would be to
|
|||
|
let range() behave like the function irange() of PEP 212 when
|
|||
|
supplied with a sequence.
|
|||
|
|
|||
|
Example:
|
|||
|
|
|||
|
>>> range(5)
|
|||
|
[0, 1, 2, 3, 4]
|
|||
|
>>> range('abcde')
|
|||
|
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]
|
|||
|
|
|||
|
|
|||
|
Backwards Compatibility
|
|||
|
|
|||
|
The proposal could cause backwards incompatibilities if arguments
|
|||
|
are used which implement both __int__ and __len__ (or __iter__ in
|
|||
|
the case of lazy iteration with xrange). The author does not
|
|||
|
believe that this is a significant problem.
|
|||
|
|
|||
|
|
|||
|
References and Footnotes
|
|||
|
|
|||
|
[1] PEP 212, Loop Counter Iteration
|
|||
|
http://www.python.org/peps/pep-0212.html
|
|||
|
|
|||
|
|
|||
|
Copyright
|
|||
|
|
|||
|
This document has been placed in the public domain.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Local Variables:
|
|||
|
mode: indented-text
|
|||
|
indent-tabs-mode: nil
|
|||
|
fill-column: 70
|
|||
|
End:
|