Pre-PEP: reverse iteration methods
Raymond Hettinger
vze4rx4y at verizon.net
Wed Sep 24 14:18:03 EDT 2003
[Raymond]
> >Abstract
> >========
> >
> >This proposal is to extend the API of several sequence types
> >to include methods for iterating over the sequence in reverse.
[Christos TZOTZIOY Georgiou]
> -0
>
> I believe this should be a function in itertools.
>
> For indexable sequences, a little modification of itertools.islice would
> do the trick, since it can't at the moment; it's designed for forward
> iteration.
>
> Helpful error messages:
> >>> itertools.islice(lst, len(lst)-1, -1, -1)
> ValueError: Stop argument must be an integer or None.
> >>> itertools.islice(lst, len(lst)-1, None, -1)
> ValueError: Step must be one or larger for islice().
>
> For non-indexable sequences (eg a file object), things get hairier, but
> given enough memory, it's not hard.
Here's a quick and dirty implementation of your idea (kept separate
from islice for clarity). On the plus side, it is somewhat clean and
easy to use. On the minus side:
* It's slower than custom iterator methods
* It behaves badly with infinite iterators as inputs
* For non-indexables, it silently transitions into a
non-lazy, memory intensive mode with a long
delay on the first call. In my opinion, this defeats
the purpose of using iterators in the first place.
def ireverse(obj):
assert not hasattr(obj, 'keys')
try:
for i in xrange(len(obj)-1, -1, -1):
yield obj[i]
except (AttributeError, TypeError):
x = list(obj) # XXX fails with infinite iterators
x.reverse()
for elem in x:
yield elem
for i in ireverse(xrange(5)):
print i
for c in ireverse('abcde'):
print c
for elem in ireverse(['atom', 'beta', 'curry']):
print elem
for line in ireverse(file('/autoexec.bat')):
print line.rstrip()
for x in reverse(itertools.count()):
# Never gets here and Python dies with a MemoryError
# from the infinite loop
pass
Raymond Hettinger
More information about the Python-list
mailing list