""" lastiter.py -- V.1.0, Jan 25 2007, by leonardo maffi Ispired by: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/304373 """ class Lastiter(object): """Lastiter(iterable): this class is like iter(), but it starts yielding items from the second one. Lastiter has a "last" property that returns the precedent item of the iterable. Useful when you need computations that need two successive items of an iterable, like two lines in a file, two elements given by groupby, etc. Example usage, note the first is missing: >>> list(Lastiter(xrange(6))) [1, 2, 3, 4, 5] >>> d = Lastiter(xrange(6)) >>> d.last 0 >>> for x in d: print x, d.last 1 0 2 1 3 2 4 3 5 4 >>> d = Lastiter([0, 1]) >>> d.last 0 >>> for x in d: print x, d.last 1 0 >>> d = Lastiter([0]) >>> d.last 0 >>> for x in d: print x, d.last >>> d = Lastiter([]) >>> d.last Traceback (most recent call last): ... StopIteration >>> for x in d: print x, d.last >>> data = [1, 4, 8, 11, 11, 11, 14, 14, 15, 21, 24, 24, 25, 25, 27] >>> ldata = Lastiter(data) >>> [el-ldata.last for el in ldata] # differential [3, 4, 3, 0, 0, 3, 0, 1, 6, 3, 0, 1, 0, 2] """ # Ispired by: # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/304373 def __init__(self, iterable): self._iterable = iter(iterable) try: self._last = self._iterable.next() except StopIteration: self._empty = True else: self._empty = False self._first = True def __iter__(self): return self def next(self): if self._first: self._first = False else: self._last = self._pred self._pred = self._iterable.next() return self._pred def get_last(self): if self._empty: raise StopIteration return self._last def set_last(self, x): raise TypeError("last can't be modified") last = property(get_last, set_last) if __name__ == "__main__": import doctest doctest.testmod() print "Doctests finished.\n" print "A small demo, gives lesser of twin primes:" print "See: http://www.research.att.com/~njas/sequences/A001359" print def xsieve(): # Copied from See xsieve in primes.py, see that for better documentation "yields the sequence of primes via the Sieve of Eratosthenes, code by D. Eppstein." yield 2 roots = xsieve() root = roots.next() square = root*root D = {} n = 3 while True: if n >= square: # Time to include another square? D[square] = root+root root = roots.next() square = root*root if n not in D: # Not witnessed, must be prime. yield n else: # Move witness p to next free multiple. p = D[n] q = n+p while q in D: q += p del D[n] D[q] = p n += 2 # Move on to next odd number. from itertools import islice lxsieve = Lastiter(xsieve()) twin_primes = (lxsieve.last for p in lxsieve if p-lxsieve.last == 2) for tp in islice(twin_primes, 0, 100): print tp, print primes = xsieve() last = primes.next() nout = 0 while nout < 100: prime = primes.next() if prime - last == 2: nout += 1 print last, last = prime print