[Python-ideas] look ahead iterators

Ron Adam rrr at ronadam.com
Wed Jul 25 23:48:32 CEST 2007



Arnaud Delobelle wrote:
> Hi,
> 
> Several people have felt the need to be able to 'peek ahead' for the next
> value of an iterator without actually retrieving it.  I have, and I have a
> 'peekable' class that I use to wrap around iterators when I need this
> feature:
> 
>>>> it = iter('python')
>>>> it = peekable(it)
>>>> it.peek(), it.peek(), it.next(), it.peek(), it.next(), it.next()
> ('p', 'p', 'p', 'y', 'y', 't')
> 
> There is an example of implementation at:
> 
> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/304373

I thought maybe the new .send() method might be good for this, but it's 
wasn't at all obvious how to do it.  (I'm still not sure if this is correct 
and doesn't have weird behaviors.)

Note:  While writing this I came across the following error... is there a 
way we can get rid of this silly requirement?

      TypeError: can't send non-None value to a just-started generator



def insert_iter(it):
     """
         An insertable iterator.

         it.send(value) -> puts value in the iterator.
     """
     it = iter(it)
     buff = []
     while 1:
         if buff:
             nv = yield buff.pop(0)
         else:
             nv = yield it.next()
         while nv:
             buff.append(nv)
             nv = yield nv


it = insert_iter('python')
print (it.send(it.next()),    # send it back, so it is avialable again.
        it.send(it.next()),
        it.next(),
        it.send(it.next()),
        it.next(),
        it.next())

PRINTS:
('p', 'p', 'p', 'y', 'y', 't')



# Output of one iterator inserted into another
# with extra content added.

it2 = insert_iter([0])      # Needs at least one item
it2.next()                  # to avoid silly error.  :(
for c1 in 'Hello world.':
     it2.send(c1)
     if c1 == ' ':
         for c2 in 'python ':
             it2.send(c2)

print ''.join(it2)


PRINTS:
Hello python world.








More information about the Python-ideas mailing list