Moved all the Open Issues to Resolved Issues, with a brief explanation
of how they were resolved. Mark this PEP as Final.
This commit is contained in:
parent
28ea10a7a4
commit
fdf0d91a18
176
pep-0234.txt
176
pep-0234.txt
|
@ -2,7 +2,7 @@ PEP: 234
|
|||
Title: Iterators
|
||||
Version: $Revision$
|
||||
Author: ping@lfw.org (Ka-Ping Yee), guido@python.org (Guido van Rossum)
|
||||
Status: Draft
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Python-Version: 2.1
|
||||
Created: 30-Jan-2001
|
||||
|
@ -254,87 +254,6 @@ Rationale
|
|||
concise and readable.
|
||||
|
||||
|
||||
Open Issues
|
||||
|
||||
The following questions are still open.
|
||||
|
||||
- The name iter() is an abbreviation. Alternatives proposed
|
||||
include iterate(), traverse(), but these appear too long.
|
||||
Python has a history of using abbrs for common builtins,
|
||||
e.g. repr(), str(), len().
|
||||
|
||||
- Using the same name for two different operations (getting an
|
||||
iterator from an object and making an iterator for a function
|
||||
with an sentinel value) is somewhat ugly. I haven't seen a
|
||||
better name for the second operation though, and since they both
|
||||
return an iterator, it's easy to remember.
|
||||
|
||||
- Once a particular iterator object has raised StopIteration, will
|
||||
it also raise StopIteration on all subsequent next() calls?
|
||||
Some say that it would be useful to require this, others say
|
||||
that it is useful to leave this open to individual iterators.
|
||||
Note that this may require an additional state bit for some
|
||||
iterator implementations (e.g. function-wrapping iterators).
|
||||
|
||||
- It has been proposed that a file object should be its own
|
||||
iterator, with a next() method returning the next line. This
|
||||
has certain advantages, and makes it even clearer that this
|
||||
iterator is destructive. The disadvantage is that this would
|
||||
make it even more painful to implement the "sticky
|
||||
StopIteration" feature proposed in the previous bullet.
|
||||
|
||||
- Some folks have requested extensions of the iterator protocol,
|
||||
e.g. prev() to get the previous item, current() to get the
|
||||
current item again, finished() to test whether the iterator is
|
||||
finished, and maybe even others, like rewind(), __len__(),
|
||||
position().
|
||||
|
||||
While some of these are useful, many of these cannot easily be
|
||||
implemented for all iterator types without adding arbitrary
|
||||
buffering, and sometimes they can't be implemented at all (or
|
||||
not reasonably). E.g. anything to do with reversing directions
|
||||
can't be done when iterating over a file or function. Maybe a
|
||||
separate PEP can be drafted to standardize the names for such
|
||||
operations when the are implementable.
|
||||
|
||||
- There is still discussion about whether
|
||||
|
||||
for x in dict: ...
|
||||
|
||||
should assign x the successive keys, values, or items of the
|
||||
dictionary. The symmetry between "if x in y" and "for x in y"
|
||||
suggests that it should iterate over keys. This symmetry has been
|
||||
observed by many independently and has even been used to "explain"
|
||||
one using the other. This is because for sequences, "if x in y"
|
||||
iterates over y comparing the iterated values to x. If we adopt
|
||||
both of the above proposals, this will also hold for
|
||||
dictionaries.
|
||||
|
||||
The argument against making "for x in dict" iterate over the keys
|
||||
comes mostly from a practicality point of view: scans of the
|
||||
standard library show that there are about as many uses of "for x
|
||||
in dict.items()" as there are of "for x in dict.keys()", with the
|
||||
items() version having a small majority. Presumably many of the
|
||||
loops using keys() use the corresponding value anyway, by writing
|
||||
dict[x], so (the argument goes) by making both the key and value
|
||||
available, we could support the largest number of cases. While
|
||||
this is true, I (Guido) find the correspondence between "for x in
|
||||
dict" and "if x in dict" too compelling to break, and there's not
|
||||
much overhead in having to write dict[x] to explicitly get the
|
||||
value.
|
||||
|
||||
For fast iteration over items, use "for key, value in
|
||||
dict.iteritems()". I've timed the difference between
|
||||
|
||||
for key in dict: dict[key]
|
||||
|
||||
and
|
||||
|
||||
for key, value in dict.iteritems(): pass
|
||||
|
||||
and found that the latter is only about 7% faster.
|
||||
|
||||
|
||||
Resolved Issues
|
||||
|
||||
The following topics have been decided by consensus or BDFL
|
||||
|
@ -400,6 +319,99 @@ Resolved Issues
|
|||
that the symmetry between lists and dictionaries is very weak,
|
||||
this argument does not have much weight.
|
||||
|
||||
- The name iter() is an abbreviation. Alternatives proposed
|
||||
include iterate(), traverse(), but these appear too long.
|
||||
Python has a history of using abbrs for common builtins,
|
||||
e.g. repr(), str(), len().
|
||||
|
||||
Resolution: iter() it is.
|
||||
|
||||
- Using the same name for two different operations (getting an
|
||||
iterator from an object and making an iterator for a function
|
||||
with an sentinel value) is somewhat ugly. I haven't seen a
|
||||
better name for the second operation though, and since they both
|
||||
return an iterator, it's easy to remember.
|
||||
|
||||
Resolution: the builtin iter() takes an optional argument, which
|
||||
is the sentinel to look for.
|
||||
|
||||
- Once a particular iterator object has raised StopIteration, will
|
||||
it also raise StopIteration on all subsequent next() calls?
|
||||
Some say that it would be useful to require this, others say
|
||||
that it is useful to leave this open to individual iterators.
|
||||
Note that this may require an additional state bit for some
|
||||
iterator implementations (e.g. function-wrapping iterators).
|
||||
|
||||
Resolution: once StopIteration is raised, calling it.next()
|
||||
continues to raise StopIteration.
|
||||
|
||||
- It has been proposed that a file object should be its own
|
||||
iterator, with a next() method returning the next line. This
|
||||
has certain advantages, and makes it even clearer that this
|
||||
iterator is destructive. The disadvantage is that this would
|
||||
make it even more painful to implement the "sticky
|
||||
StopIteration" feature proposed in the previous bullet.
|
||||
|
||||
Resolution: this has been implemented.
|
||||
|
||||
- Some folks have requested extensions of the iterator protocol,
|
||||
e.g. prev() to get the previous item, current() to get the
|
||||
current item again, finished() to test whether the iterator is
|
||||
finished, and maybe even others, like rewind(), __len__(),
|
||||
position().
|
||||
|
||||
While some of these are useful, many of these cannot easily be
|
||||
implemented for all iterator types without adding arbitrary
|
||||
buffering, and sometimes they can't be implemented at all (or
|
||||
not reasonably). E.g. anything to do with reversing directions
|
||||
can't be done when iterating over a file or function. Maybe a
|
||||
separate PEP can be drafted to standardize the names for such
|
||||
operations when the are implementable.
|
||||
|
||||
Resolution: rejected.
|
||||
|
||||
- There is still discussion about whether
|
||||
|
||||
for x in dict: ...
|
||||
|
||||
should assign x the successive keys, values, or items of the
|
||||
dictionary. The symmetry between "if x in y" and "for x in y"
|
||||
suggests that it should iterate over keys. This symmetry has been
|
||||
observed by many independently and has even been used to "explain"
|
||||
one using the other. This is because for sequences, "if x in y"
|
||||
iterates over y comparing the iterated values to x. If we adopt
|
||||
both of the above proposals, this will also hold for
|
||||
dictionaries.
|
||||
|
||||
The argument against making "for x in dict" iterate over the keys
|
||||
comes mostly from a practicality point of view: scans of the
|
||||
standard library show that there are about as many uses of "for x
|
||||
in dict.items()" as there are of "for x in dict.keys()", with the
|
||||
items() version having a small majority. Presumably many of the
|
||||
loops using keys() use the corresponding value anyway, by writing
|
||||
dict[x], so (the argument goes) by making both the key and value
|
||||
available, we could support the largest number of cases. While
|
||||
this is true, I (Guido) find the correspondence between "for x in
|
||||
dict" and "if x in dict" too compelling to break, and there's not
|
||||
much overhead in having to write dict[x] to explicitly get the
|
||||
value.
|
||||
|
||||
For fast iteration over items, use "for key, value in
|
||||
dict.iteritems()". I've timed the difference between
|
||||
|
||||
for key in dict: dict[key]
|
||||
|
||||
and
|
||||
|
||||
for key, value in dict.iteritems(): pass
|
||||
|
||||
and found that the latter is only about 7% faster.
|
||||
|
||||
Resolution: By BDFL pronouncement, "for x in dict" iterates over
|
||||
the keys, and dictionaries have iteritems(), iterkeys(), and
|
||||
itervalues() to return the different flavors of dictionary
|
||||
iterators.
|
||||
|
||||
|
||||
Mailing Lists
|
||||
|
||||
|
|
Loading…
Reference in New Issue