[Python-Dev] Re: PEP 322: Reverse Iteration

Samuele Pedroni pedronis at bluewin.ch
Wed Nov 5 16:44:59 EST 2003


At 19:14 05.11.2003 +0100, Alex Martelli wrote:
>On Wednesday 05 November 2003 05:34 pm, Samuele Pedroni wrote:
>    ...
> > I think he was wondering whether people rely on
> >
> > enumerate([1,2]).next
> > i = enumerate([1,2])
> > i is iter(i)
> >
> > working , vs. needing iter(enumerate([1,2]).next
> >
> > I think he was proposing to implement enumerate as
> >
> > class enumerate(object):
> >    def __init__(self,iterable):
> >      self.iterable = iterable
> >
> >    def __iter__(self):
> >      i = 0
> >      for x in self.iterable:
> >        yield i,x
> >        i += 1
> >
> >    def __reversed__(self):
> >      rev = reversed(self.iterable)
> >      try:
> >        i = len(self.iterable)-1
> >      except (TypeError,AttributeError):
> >        i = -1
> >      for x in rev:
> >         yield i,x
> >         i -= 1
>
>Ah, I see -- thanks!  Well, in theory you COULD add a 'next' method too:
>
>       def next(self):
>           self.iterable = iter(self.iterable)
>           try: self.index += 1
>           except AttributeError: self.index = 0
>           return self.index, self.iterable.next()
>
>(or some reasonable optimization thereof:-) -- now __reversed__ would stop
>working after any .next call, but that would still be OK for all use cases I
>can think of.

well, you would also get an iterator hybrid that violates:

"""
Iterator objects also need to implement this method [__iter__]; they are 
required to return themselves.
"""

http://www.python.org/doc/2.3.2/ref/sequence-types.html#l2h-234

what one could do is:

  class enumerate(object):
    def __init__(self,iterable):
      self.iterable = iterable
       self.forward = None
       self.index = 0

     def __iter__(self):
       return self

    def next(self):
        if not self.forward:
           self.forward = iter(self.iterable)
        i = self.index
        self.index += 1
       return i, self.forward.next()

    def __reversed__(self):
      if self.forward:
         raise Exception,...

     rev = reversed(self.iterable)
     try:
        i = len(self.iterable)-1
     except (TypeError,AttributeError):
        i = -1
     for x in rev:
        yield i,x
        i -= 1

but is still an hybrid, setting a bad precedent of trying too hard to 
attach __reversed__ to an iterator, making enumerate just an iterable is 
not backward compatible but is a bit saner although it does not feel that 
natural either.

regards. 




More information about the Python-Dev mailing list