[Python-Dev] PEP 322: Reverse Iteration

Moore, Paul Paul.Moore at atosorigin.com
Wed Nov 5 08:50:47 EST 2003


From: Jeremy Fincher [mailto:fincher.8 at osu.edu]
> If this proposal could be satisfied by the simple definition:
>
> def reversed(seq):
>     for i in xrange(len(seq)-1, -1, -1):
>         yield seq[i]
>
> I wouldn't be for it.  The reason I'm +1 is because I want
> a standard protocol for iterating in reverse over objects.

The more I think about it, the less I see the need for reversed(). But I'm
having a really difficult time articulating why.

I don't see enough use cases for something which just reverses sequences,
as above. I tend to loop over concrete sequences less and less these days,
using iterators, generators, enumerate, itertools etc, far more. The simple
reversed() above doesn't help at all there. OK, reversed([x]range) is useful,
but as soon as an iterator-based irange existed, I'd use that for "forward"
loops, and be most upset that reversed(irange) didn't work...

Whenever I try to play with writing a reversed() which is more general than
the code above, I get stuck because *something* needs reversing, but it's
virtually never a sequence!

So far, I've needed to reverse:

    itertools.count()
    itertools.zip()
    enumerate()

But this is all fairly incestuous - all I'm proving is that *if* you need
reversed() on something other than a sequence, you can't do it without
help from something (the object itself, or something else). But the cases
*I* care about have been pre-existing Python objects, which Raymond is not
proposing to extend in that way! (I can see that having the __reversed__
protocol may help with user-defined objects, I just don't have such a need
myself).

I'm tending to come down in favour of just having a simple "generate
numbers in reverse" function (whether that is irange(..., reverse=True) or
irevrange, or something else). Like Guido, I think that covers most real
cases. Especially in combination with itertools -

    reversed(seq) <===> imap(seq.__getitem__, irevrange(len(seq)))

Hmm, that reads better with irevrange. Looks like Guido's judgement is
right again...

Actually, itertools.count() looks very much like it's relevant here. It has
a start argument (defaulting to 0) but no stop or step. Maybe we should be
extending this, rather than inventing a new itertool.

    count(start=0, end=<forever>, step=1, reverse=False)

This adds a *lot* of generality to count. Or how about itertools.count() as
above, and itertools.countdown() as a reversed version?

OK. I think I've changed to -0 on PEP 322, and +1 on having irange and
irevrange (or an extended count and countdown) in itertools.

Paul.



More information about the Python-Dev mailing list