On Apr 28, 6:38 pm, "J. Cliff Dyer" <j...@sdf.lonestar.org> wrote: > On Tue, 2009-04-28 at 10:41 +0000, Duncan Booth wrote: > > Lacrima <lacrima.ma...@gmail.com> wrote: > > > > If it is not possible what are common techniques to use iterator or > > > generator objects that allow restarting when it is needed? > > > The usual thing if you want to use the generator's output more than once > > would be to convert the generator to a list, then you can iterate over it > > as often as you want. > > > >>> a = ['a', 'b', 'c'] > > >>> g = (i for i in a) > > >>> restartable = list(g) > > > If you want the output of the generator to potentially change each time you > > iterate then you need to create a new generator. > > More verbosely, but without putting your generator in , you can use the > iterator protocol to create a reusable iterable: > > An iterable is a class with an __iter__ method that returns an iterator. > > So for example: > > class Iterator(object): > def __init__(self, filename): > self.f = open(filename) > > def __iter__(self): > return self > > def next(self): > line = self.f.readline() > if not line: > raise StopIteration > return line.strip()[:8] > > is an iterator (which is also an iterable), which will grab each line of > a file, returning the first eight non-whitespace characters until the > file is used up. Then the iterator is exhausted, and will continue to > raise StopIteration each time it is called. > > class Iterable(object): > def __init__(self, filename): > self.filename = filename > > def __iter__(self): > return Iterator(self.filename) > > This is a reusable iterable which returns a new instance of the Iterator > class above each time it is exhausted. > > So given a file hello.txt: > > Hello world > Hola mundo > Guten tag, weld. > > The classes can be used as followed:>>> iterator = Iterator('hello.txt') > >>> for i in xrange(3): > >>> print "*** %d ***" % i > >>> for j in iterator: > >>> print j > > *** 0 *** > Hello wo > Hola mun > Guten ta > *** 1 *** > *** 2 ***>>> iterable = Iterable('hello.txt') > >>> for i in xrange(3): > >>> print "*** %d ***" % i > >>> for j in iterable: > >>> print j > > *** 0 *** > Hello wo > Hola mun > Guten ta > *** 1 *** > Hello wo > Hola mun > Guten ta > *** 2 *** > Hello wo > Hola mun > Guten ta > > When Iterator hits a StopIteration, it passes out of the inner loop, and > when it comes back in, the inner loop calls iterator.__iter__(), and > gets the same exhausted iterator (which immediately breaks the inner > loop by raising StopIteration). In Iterable, when the loop calls > iterable.__iter__(), it gets a fresh iterator, so it can loop over the > file again. > > The important thing is that when you call x.__iter__() (which you do > when entering a loop), you get a fresh iterator that won't just call > StopIteration right away. > > Cheers, > Cliff
Thank you very much! You completely have enlightened me on all my questions! -Max -- http://mail.python.org/mailman/listinfo/python-list