[Python-Dev] Re: Reiterability

Guido van Rossum guido at python.org
Sun Oct 19 21:04:14 EDT 2003


FWIW, I partially withdraw my observation that reiterability is a
special case of cloneability.  It is true that if you have
cloneability you have reiterability.  But I hadn't realized that
reiterability is sometimes easier than cloneability!

Cloning a generator function at an arbitrary point is not doable; but
cloning a generator function at the start would be as easy as saving
the function and its arguments.

But this doesn't make me any more comfortable with the idea of adding
reiterability as an iterator feature (even optional).

An iterator represents the rest of the sequence of values it will
generate.  But if we add reiterability into the mix, an iterator
represents two different sequences: its "full" sequence, accessible
via its reiter() method (or whatever it would be called), and its
"current" sequence.  The latter may be different, because when you get
passed an iterator, whoever passed it might already have consumed some
items; this affects the "current" sequence but not the sequence
returned by reiter().  (Cloning doesn't have this problem, but its
other problems make up for this.)

If you prefer to see a code sample explaining the problem: consider a
consumer of a reiterable iterator:

  def printwice(it):
      for x in it: print x
      for x in it.reiter(): print x

Now suppose the following code that calls it:

  r = range(10)
  it = iter(r) # assume this is reiterable
  it.next()    # skip first item
  printwice(it)

This prints 1...9 followed by 0...9 !!!  The solution using cloning
wouldn't have this problem:

  def printwice(it):
      it2 = it.clone()
      for x in it: print x
      for x in it2: print x

With reiter() it becomes hard to explain what the input requirements
are for the function to work correctly; effectively, it would require
a "virginal" (== has never been used :-) reiterable iterator.  So we
might as well require a container!  If you don't have a container but
you have a description of a series, Alex's Reiterable can easily fix
this:

  class Reiterable:
      def __init__(self, func, *args):
          self.func, self.args = func, args
      def __iter__(self):
          return self.func(*self.args)

This should be called with e.g. a generator function and an argument
list for it.

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



More information about the Python-Dev mailing list