James's last update, and mark this PEP rejected.
This commit is contained in:
parent
73238e3409
commit
e4dbb1a74a
206
pep-0276.txt
206
pep-0276.txt
|
@ -3,7 +3,7 @@ Title: Simple Iterator for ints
|
||||||
Version: $Revision$
|
Version: $Revision$
|
||||||
Last-Modified: $Date$
|
Last-Modified: $Date$
|
||||||
Author: james_althoff@i2.com (Jim Althoff)
|
Author: james_althoff@i2.com (Jim Althoff)
|
||||||
Status: Draft
|
Status: Rejected
|
||||||
Type: Standards Track
|
Type: Standards Track
|
||||||
Created: 12-Nov-2001
|
Created: 12-Nov-2001
|
||||||
Python-Version: 2.3
|
Python-Version: 2.3
|
||||||
|
@ -97,13 +97,13 @@ Rationale
|
||||||
indexed for-loop idiom is to use the builtin range() or xrange()
|
indexed for-loop idiom is to use the builtin range() or xrange()
|
||||||
function to generate a sequence of indices as in, for example:
|
function to generate a sequence of indices as in, for example:
|
||||||
|
|
||||||
for rowcount in range(table.getRowCount()):
|
for rowcount in range(table.getRowCount()):
|
||||||
print table.getValueAt(rowcount, 0)
|
print table.getValueAt(rowcount, 0)
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
for rowcount in xrange(table.getRowCount()):
|
for rowcount in xrange(table.getRowCount()):
|
||||||
print table.getValueAt(rowcount, 0)
|
print table.getValueAt(rowcount, 0)
|
||||||
|
|
||||||
From time to time there are discussions in the Python community
|
From time to time there are discussions in the Python community
|
||||||
about the indexed for-loop idiom. It is sometimes argued that the
|
about the indexed for-loop idiom. It is sometimes argued that the
|
||||||
|
@ -161,8 +161,8 @@ Rationale
|
||||||
would enable by default the following shortcut for the indexed
|
would enable by default the following shortcut for the indexed
|
||||||
for-loop idiom:
|
for-loop idiom:
|
||||||
|
|
||||||
for rowcount in table.getRowCount():
|
for rowcount in table.getRowCount():
|
||||||
print table.getValueAt(rowcount, 0)
|
print table.getValueAt(rowcount, 0)
|
||||||
|
|
||||||
The following benefits for this approach vis-a-vis the current
|
The following benefits for this approach vis-a-vis the current
|
||||||
mechanism of using the range() or xrange() functions are claimed
|
mechanism of using the range() or xrange() functions are claimed
|
||||||
|
@ -190,10 +190,6 @@ Rationale
|
||||||
included (as of Python 2.1) for other builtin types such as:
|
included (as of Python 2.1) for other builtin types such as:
|
||||||
lists, tuples, dictionaries, strings, and files.
|
lists, tuples, dictionaries, strings, and files.
|
||||||
|
|
||||||
Preliminary discussion on the Python interest mailing list
|
|
||||||
suggests a reasonable amount of initial support for this PEP
|
|
||||||
(along with some dissents/issues noted below).
|
|
||||||
|
|
||||||
|
|
||||||
Backwards Compatibility
|
Backwards Compatibility
|
||||||
|
|
||||||
|
@ -210,8 +206,8 @@ Backwards Compatibility
|
||||||
1) The common case where one forgets to include range() or
|
1) The common case where one forgets to include range() or
|
||||||
xrange(), for example:
|
xrange(), for example:
|
||||||
|
|
||||||
for rowcount in table.getRowCount():
|
for rowcount in table.getRowCount():
|
||||||
print table.getValueAt(rowcount, 0)
|
print table.getValueAt(rowcount, 0)
|
||||||
|
|
||||||
in Python 2.2 raises a TypeError exception.
|
in Python 2.2 raises a TypeError exception.
|
||||||
|
|
||||||
|
@ -238,11 +234,32 @@ Backwards Compatibility
|
||||||
relatively easy to correct should it happen.
|
relatively easy to correct should it happen.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Issues:
|
Issues:
|
||||||
|
|
||||||
Based on some preliminary discussion on the Python interest
|
Extensive discussions concerning PEP 276 on the Python interest
|
||||||
mailing list, the following concerns have been voiced:
|
mailing list suggests a range of opinions: some in favor, some
|
||||||
|
neutral, some against. Those in favor tend to agree with the
|
||||||
|
claims above of the usefulness, convenience, ease of learning,
|
||||||
|
and simplicity of a simple iterator for integers.
|
||||||
|
|
||||||
|
Issues with PEP 276 include:
|
||||||
|
|
||||||
|
- Using range/xrange is fine as is.
|
||||||
|
|
||||||
|
Response: Some posters feel this way. Other disagree.
|
||||||
|
|
||||||
|
- Some feel that iterating over the sequence "0, 1, 2, ..., n-1"
|
||||||
|
for an integer n is not intuitive. "for i in 5:" is considered
|
||||||
|
(by some) to be "non-obvious", for example. Some dislike this
|
||||||
|
usage because it doesn't have "the right feel". Some dislike it
|
||||||
|
because they believe that this type of usage forces one to view
|
||||||
|
integers as a sequences and this seems wrong to them. Some
|
||||||
|
dislike it because they prefer to view for-loops as dealing
|
||||||
|
with explicit sequences rather than with arbitrary iterators.
|
||||||
|
|
||||||
|
Response: Some like the proposed idiom and see it as simple,
|
||||||
|
elegant, easy to learn, and easy to use. Some are neutral on
|
||||||
|
this issue. Others, as noted, dislike it.
|
||||||
|
|
||||||
- Is it obvious that iter(5) maps to the sequence 0,1,2,3,4?
|
- Is it obvious that iter(5) maps to the sequence 0,1,2,3,4?
|
||||||
|
|
||||||
|
@ -250,17 +267,12 @@ Issues:
|
||||||
convention for indexing sequences starting at 0 and stopping at
|
convention for indexing sequences starting at 0 and stopping at
|
||||||
(inclusively) the index whose value is one less than the length
|
(inclusively) the index whose value is one less than the length
|
||||||
of the sequence, it is argued that the proposed sequence is
|
of the sequence, it is argued that the proposed sequence is
|
||||||
reasonably intuitive to a Python programmer while being useful
|
reasonably intuitive to the Python programmer while being useful
|
||||||
and practical.
|
and practical. More importantly, it is argued that once learned
|
||||||
|
this convention is very easy to remember. Note that the doc
|
||||||
- "in" (as in "for i in x") does not match standard English usage
|
string for the range function makes a reference to the
|
||||||
in this case. "up to" or something similar might be better.
|
natural and useful association between range(n) and the indices
|
||||||
|
for a list whose length is n.
|
||||||
Response: Not everyone felt that matching standard English
|
|
||||||
perfectly is a requirement. It is noted that "for:else:"
|
|
||||||
doesn't match standard English very well either. And few are
|
|
||||||
excited about adding a new keyword, especially just to get a
|
|
||||||
somewhat better match to standard English usage.
|
|
||||||
|
|
||||||
- Possible ambiguity
|
- Possible ambiguity
|
||||||
|
|
||||||
|
@ -268,104 +280,110 @@ Issues:
|
||||||
|
|
||||||
might be mistaken for
|
might be mistaken for
|
||||||
|
|
||||||
for i in (10,): print i
|
for i in (10,): print i
|
||||||
|
|
||||||
Response: The predicted ambiguity was not readily apparent to
|
Response: This is exactly the same situation with strings in
|
||||||
several of the posters.
|
current Python (replace 10 with 'spam' in the above, for
|
||||||
|
example).
|
||||||
|
|
||||||
- It would be better to add special new syntax such as:
|
- Too general: in the newest releases of Python there are
|
||||||
|
contexts -- as with for-loops -- where iterators are called
|
||||||
|
implicitly. Some fear that having an iterator invoked for
|
||||||
|
an integer in one of the context (excluding for-loops) might
|
||||||
|
lead to unexpected behavior and bugs. The "x, = 1" example
|
||||||
|
noted above is an a case in point.
|
||||||
|
|
||||||
for i in 0..10: print i
|
Response: From the author's perspective the examples of the
|
||||||
|
above that were identified in the PEP 276 discussions did
|
||||||
|
not appear to be ones that would be accidentally misused
|
||||||
|
in ways that would lead to subtle and hard-to-detect errors.
|
||||||
|
|
||||||
Response: There are other PEPs that take this approach[2][3].
|
In addition, it seems that there is a way to deal with this
|
||||||
|
issue by using a variation of what is outlined in the
|
||||||
|
specification section of this proposal. Instead of adding
|
||||||
|
an __iter__ method to class int, change the for-loop handling
|
||||||
|
code to convert (in essense) from
|
||||||
|
|
||||||
- It would be better to reuse the ellipsis literal syntax (...)
|
for i in n: # when isinstance(n,int) is 1
|
||||||
|
|
||||||
Response: Shares disadvantages of other proposals that require
|
to
|
||||||
changes to the syntax. Needs more design to determine how it
|
|
||||||
would handle the general case of start,stop,step,
|
|
||||||
open/closed/half-closed intervals, etc. Needs a PEP.
|
|
||||||
|
|
||||||
- It would be better to reuse the slicing literal syntax attached
|
for i in xrange(n):
|
||||||
to the int class, e.g., int[0:10]
|
|
||||||
|
|
||||||
Response: Same as previous response. In addition, design
|
This approach gives the same results in a for-loop as an
|
||||||
consideration needs to be given to what it would mean if one
|
__iter__ method would but would prevent iteration on integer
|
||||||
uses slicing syntax after some arbitrary class other than class
|
values in any other context. Lists and tuples, for example,
|
||||||
int. Needs a PEP.
|
don't have __iter__ and are handled with special code.
|
||||||
|
Integer values would be one more special case.
|
||||||
|
|
||||||
|
- "i in n" seems very unnatural.
|
||||||
|
|
||||||
|
Response: Some feel that "i in len(mylist)" would be easily
|
||||||
|
understandable and useful. Some don't like it, particularly
|
||||||
|
when a literal is used as in "i in 5". If the variant
|
||||||
|
mentioned in the response to the previous issue is implemented,
|
||||||
|
this issue is moot. If not, then one could also address this
|
||||||
|
issue by defining a __contains__ method in class int that would
|
||||||
|
always raise a TypeError. This would then make the behavior of
|
||||||
|
"i in n" identical to that of current Python.
|
||||||
|
|
||||||
- Might dissuade newbies from using the indexed for-loop idiom when
|
- Might dissuade newbies from using the indexed for-loop idiom when
|
||||||
the standard "for item in collection:" idiom is clearly better.
|
the standard "for item in collection:" idiom is clearly better.
|
||||||
|
|
||||||
Response: The standard idiom is so nice when "it fits" that it
|
Response: The standard idiom is so nice when it fits that it
|
||||||
needs neither extra "carrot" nor "stick". On the other hand,
|
needs neither extra "carrot" nor "stick". On the other hand,
|
||||||
one does notice cases of overuse/misuse of the standard idiom
|
one does notice cases of overuse/misuse of the standard idiom
|
||||||
(due, most likely, to the awkwardness of the indexed for-loop
|
(due, most likely, to the awkwardness of the indexed for-loop
|
||||||
idiom), as in:
|
idiom), as in:
|
||||||
|
|
||||||
for item in sequence:
|
for item in sequence:
|
||||||
print sequence.index(item)
|
print sequence.index(item)
|
||||||
|
|
||||||
- Doesn't handle the general case of start,stop,step
|
- Why not propose even bigger changes?
|
||||||
|
|
||||||
Response: use the existing range() or xrange() mechanisms. Or,
|
The majority of disagreement with PEP 276 came from those who
|
||||||
see below.
|
favor much larger changes to Python to address the more general
|
||||||
|
problem of specifying a sequence of integers where such
|
||||||
|
a specification is general enough to handle the starting value,
|
||||||
|
ending value, and stepping value of the sequence and also
|
||||||
|
addresses variations of open, closed, and half-open (half-closed)
|
||||||
|
integer intervals. Many suggestions of such were discussed.
|
||||||
|
|
||||||
|
These include:
|
||||||
|
|
||||||
Extension
|
- adding Haskell-like notation for specifying a sequence of
|
||||||
|
integers in a literal list,
|
||||||
|
|
||||||
If one wants to handle general indexing (start,stop,step) without
|
- various uses of slicing notation to specify sequences,
|
||||||
having to resort to using the range() or xrange() functions then
|
|
||||||
the following could be incorporated into the current proposal.
|
|
||||||
|
|
||||||
Add an "iter" method (or use some other preferred name) to
|
- changes to the syntax of for-in loops to allow the use of
|
||||||
types.IntType with the following signature:
|
relational operators in the loop header,
|
||||||
|
|
||||||
def iter(start=0, step=1):
|
- creation of an integer-interval class along with methods that
|
||||||
|
overload relational operators or division operators
|
||||||
|
to provide "slicing" on integer-interval objects,
|
||||||
|
|
||||||
This method would have the (hopefully) obvious semantics.
|
- and more.
|
||||||
|
|
||||||
Then one could do, for example:
|
It should be noted that there was much debate but not an
|
||||||
|
overwhelming concensus for any of these larger-scale suggestions.
|
||||||
|
|
||||||
x = 100
|
Clearly, PEP 276 does not propose such a large-scale change
|
||||||
for i in x.iter(start=1, step=2):
|
and instead focuses on a specific problem area. Towards the
|
||||||
print i
|
end of the discussion period, several posters expressed favor
|
||||||
|
for the narrow focus and simplicity of PEP 276 vis-a-vis the more
|
||||||
Under this extension (for x bound to an int),
|
ambitious suggestions that were advanced. There did appear to be
|
||||||
|
concensus for the need for a PEP for any such larger-scale,
|
||||||
for i in x:
|
alternative suggestion. In light of this recognition, details of
|
||||||
|
the various alternative suggestions are not discussed here further.
|
||||||
would be equivalent to
|
|
||||||
|
|
||||||
for i in x.iter():
|
|
||||||
|
|
||||||
and to
|
|
||||||
|
|
||||||
for i in x.iter(start=0, step=1):
|
|
||||||
|
|
||||||
This extension is consistent with the generalization provided by
|
|
||||||
the current mechanism for dictionaries whereby one can use:
|
|
||||||
|
|
||||||
for k in d.iterkeys():
|
|
||||||
for v in d.itervalues():
|
|
||||||
for k,v in d.iteritems():
|
|
||||||
|
|
||||||
depending on one's needs, given that
|
|
||||||
|
|
||||||
for i in d:
|
|
||||||
|
|
||||||
has a meaning aimed at the most common and useful case (d.iterkeys()).
|
|
||||||
|
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
An implementation is not available at this time and although the
|
An implementation is not available at this time but is expected
|
||||||
author is not qualified to comment on such he will, nonetheless,
|
to be straightforward. The author has implemented a subclass of
|
||||||
speculate that this might be straightforward and, hopefully, might
|
int with an __iter__ method (written in Python) as a means to test
|
||||||
consist of little more than setting the tp_iter slot in
|
out the ideas in this proposal, however.
|
||||||
types.IntType to point to a simple iterator function that would be
|
|
||||||
similar to -- or perhaps even a wrapper around -- the xrange()
|
|
||||||
function.
|
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
|
|
Loading…
Reference in New Issue