Peek inside iterator (is there a PEP about this?)

Lie Ryan lie.1296 at gmail.com
Wed Oct 1 13:22:32 EDT 2008


On Wed, 01 Oct 2008 10:46:33 -0400, Luis Zarrabeitia wrote:

> Hi there.
> 
> For most use cases I think about, the iterator protocol is more than
> enough. However, on a few cases, I've needed some ugly hacks.
> 
> Ex 1:
> 
> a = iter([1,2,3,4,5]) # assume you got the iterator from a function and
> b = iter([1,2,3])     # these two are just examples.
> 
> then,
> 
> zip(a,b)
> 
> has a different side effect from
> 
> zip(b,a)
> 
> After the excecution, in the first case, iterator a contains just [5],
> on the second, it contains [4,5]. I think the second one is correct (the
> 5 was never used, after all). I tried to implement my 'own' zip, but
> there is no way to know the length of the iterator (obviously), and
> there is also no way to 'rewind' a value after calling 'next'.
> 
> Ex 2:
> 
> Will this iterator yield any value? Like with most iterables, a
> construct
> 
> if iterator:
>    # do something
> 
> would be a very convenient thing to have, instead of wrapping a 'next'
> call on a try...except and consuming the first item.
> 
> Ex 3:
> 
> if any(iterator):
>    # do something ... but the first true value was already consumed and
>    # cannot be reused. "Any" cannot peek inside the iterator without #
>    consuming the value.
> 
> Instead,
> 
> i1, i2 = tee(iterator)
> if any(i1):
>    # do something with i2
> 
> Question/Proposal:
> 
> Has there been any PEP regarding the problem of 'peeking' inside an
> iterator? 

No (or I'm not aware of any). Why? Because for some iterable, it is not 
possible to know in advance its length (video data stream, for example), 
or whether it'd ever end (the digits of pi).

Second, in python, iterator is a use-once object, it is not designed to 
be reused. Some languages, especially the purely functional ones, allow 
multiple use of iterator because they guarantee immutability, python 
allows mutable object, and is unable to provide that.

> Knowing if the iteration will end or not, and/or accessing the
> next value, without consuming it? 

No, it is not possible to do that for some iterators. For example, this 
code:

import time
class Iterable(object):
    def __iter__(self):
        return self
    def next(self):
        return time.time()

if you peeked the iterator in advance, the result would be different 
compared to the result when you actually need it. 

> Is there any (simple, elegant) way
> around it?

Simple, but probably not that elegant, if you need such a fine control, 
use while loop.

> Cheers,
> 
> --
> Luis Zarrabeitia (aka Kyrie)
> Fac. de Matemática y Computación, UH.
> http://profesores.matcom.uh.cu/~kyrie





More information about the Python-list mailing list