class Enumerable: def __init__(self, func): self.func = func def lazydec(f): def inner(self, arg): return Enumerable(lambda: f(self, arg)) return inner @lazydec def select(self, func): for item in self.func(): yield func(item) @lazydec def inner(func): for item in self.func(): if func(item): yield item @lazydec def inner(stream): for left in self.func(): for right in stream.func(): yield (left, right) @lazydec def take(self, count): iterator = self.func() for counter in xrange(count): yield iterator.next() @lazydec def skip(self, count): iterator = self.func() for counter in xrange(count): iterator.next() while True: yield iterator.next() def __iter__(self): return self.func() #could have also used a decorator here def ezip(enum1, enum2): def inner(e1, e2): i1 = e1.__iter__() i2 = e2.__iter__() while True: yield (i1.next(), i2.next()) return Enumerable(lambda: inner(enum1,enum2)) ############################################################################### def fibs(): yield 0 yield 1 fibsEnum = Enumerable(fibs) for value in ezip(fibsEnum, fibsEnum.skip(1)).select(lambda item: item[0] + item[1]): yield value if __name__ == "__main__": fs = Enumerable(fibs) fs = fs.take(10) print list(fs)