PEP 281, Loop Counter Iteration with range and xrange, Magnus Lie
Hetland
This commit is contained in:
parent
d4757ee5a2
commit
6aa5241875
|
@ -0,0 +1,133 @@
|
|||
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:
|
Loading…
Reference in New Issue