PEP 322: Reverse Iteration (second revision, please comment)
Alex Martelli
aleax at aleax.it
Thu Oct 30 05:46:45 EST 2003
Raymond Hettinger wrote:
...
> * the sample implementation now clearly shows a check for a custom
> reverse method and a guard against being applied to a mapping.
SyntaxError: 'return' with argument inside generator
So presumably said check must be recoded in the PEP as:
try:
customiter = x.__reversed__
except AttributeError:
pass
else:
for i in customiter():
yield i
return
Yeah, sometimes it WOULD be nice if "return with argument inside
generator" automagically expanded to "for ...: yield / return".
> Also, please take a look at the revrange() alternative to see if you
> prefer it or not.
It would deal more directly with about half of my use cases but
less directly with the other half, so that's roughly a wash. But
having revrange return a list would just perpetuate the minor wart
that range has now become, and having it NOT return a list (rather
an iterator) would violate the principle of Least Surprise wrt range.
A built-in iterator irange -- with an optional "reverse=" argument,
just like the very useful one you recently added to list.sort -- would be
just as useful as revrange for the latter's use cases, AND be very handy to
me in many more cases in which I currently use xrange and cringe each and
every time. Plus, specifically, I have some uses cases where:
if mustbereversed(...):
seq = xrange(N-1, -1, -1)
else:
seq = xrange(N)
for item in seq:
...
and those would get a somewhat minor benefit from either reverse OR
revrange, since the if/else to prepare seq would still be there,
albeit more readable along one of the two branches. However, for this
kind of use case, an irange with an optional reverse= would be PERFECT:
for item in irange(N, reverse=mustbereversed(...)):
...
now THAT would be blissful indeed.
I opine irange-w-opt-parm would be by far the best solution. E.g.,
in your use case from heapq.heapify, just about custommade for
revrange, in my opinion the three possibilities:
for i in reversed(xrange(n//2)):
...
for i in revrange(n//2):
...
for i in irange(n//2, reverse=True):
...
are just about equivalent -- the concision of revrange is a very
minor benefit even here. The vastly wider usecases of irange might
in fact even let us slowly and gradually start "discouraging" the
use of range and xrange -- that will be the day... I've pined for
an irange even since the iterator protocol appeared. And the use
of the "reverse=True" idiom will be widespread and habitual anyway
thanks to the fact that it's present in list.sort as well now.
(_and_, IMHO, irange has 100% appropriateness as a builtin, given
that it would/should soon become ***one of the most widely used
constructs in Python*** -- FAR more than revrange or reversed...!).
Alex
More information about the Python-list
mailing list