[Python-iterators] Re: PEP 234: Iterators

Guido van Rossum guido at digicool.com
Tue May 1 08:33:24 EDT 2001


[PEP 234]
> > >     - Using the same name for two different operations (getting an
> > >       iterator from an object and making an iterator for a function
> > >       with an sentinel value) is somewhat ugly.  I haven't seen a
> > >       better name for the second operation though.

[Christian Tanzer]
> > I assume `ugly' refers to the implementation.

No, people were commenting that these were two very different pieces
of functionality rolled into one function.  Sort of like if len(x)
gave the length of a sequence and len(x, y) returned the greatest
common divisor of x and y.

> > As both operations return an iterator object it seems natural to use
> > the same name for them. Having to remember two different names for
> > iterator-returning operations looks ugly to me.

Thanks -- I'll use that as an argument pro in the PEP.

[Just van Rossum]
> But the usage is typically different. iter(obj) will _usually_ be used from
> within an __iter__ method, which will typically be invoked implicitly by the for
> loop. I think it will be rare for iterators created "manually" with iter(obj) to
> be passed "manually" to a for loop.

> On the other hand, the output of iter(callable, sentinel) *is* likely to be
> passed "manually" to a for loop.

The usages are indeed different, but not the way you describe.  I
wouldn't expect iter(obj) inside an __iter__() method -- this would
cause recursion, as iter(obj) calls obj.__iter__()!

The main use I see for iter(obj) is in cases like Tim's zipiter()
class.  I expect that folks used to functional programming will go
wild with the idea of writing functions that compose or slice and dice
iterators.  E.g. here's an iterator that gives the even-numbered items
of an argument iterator:

  class EvenIterator:

    def __init__(self, it):
      self.it = it

    def next(self):
      self.it.next()
      return self.it.next()

    def __iter__(self):
      return self

In order to use this, you need to pass it an iterator, not a sequence;
so if all you have is a sequence, you'd have to invoke iter() on it:

  >>> for i in EvenIterator(iter(range(10))):
        print i

  1
  3
  5
  7
  9
  >>>

> Conceptually, iter(obj) returns an iterator object, and iter(callable, sentinel)
> returns an object that can be iterated over.

No.  iter(callable, sentinel) also returns an iterator.  Period.  I
don't see how adding "conceptually" changes this. :-)

> However, due to the protocol's requirement that iter(obj) is
> equivalent to iter(iter(obj)) this duality is not visible, and
> possibly therefore not that important. However, it *is* IMHO worthy
> of the qualification "somewhat ugly", but not much more than that
> ;-)

:-)

--Guido van Rossum (home page: http://www.python.org/~guido/)




More information about the Python-list mailing list