1

I would like to be able to defer the construction of the elements of a list until they are accessed for the first time. The obvious solution (using a generator as below does not work since it is iterable more than once, etc).

For example, the following prints 0 -> 9. I would like to print 0-> 9 twice.

def costly_build_function(i):
    return i
def my_function():
    return (costly_build_function(i) for i in range(0,10))
tmp = my_function()
# print 0 to 0
for i in tmp:
    print i
# print nothing
for i in tmp:
    print i
mathieu
  • 2,954
  • 2
  • 20
  • 31

1 Answers1

4

Wrap your generator in an object that caches the results produced:

class LazyList(object):
    def __init__(self, it):
        self._cache = []
        self._it = it
    def __iter__(self):
        for item in self._cache:
            yield item
        for item in self._it:
            self._cache.append(item)
            yield item
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343