views:

66

answers:

1
+3  Q: 

just-in-time list

I'd like to know if there is a class available, either in the standard library or in pypi, that fits this description.

The constructor would take an iterator.

It would implement the container protocol (ie _getitem_, _len_, etc), so that slices, length, etc., would work. In doing so, it would iterate and retain just enough values from its constructor argument to provide whatever information was requested.

So if jitlist[6] was requested, it would call self.source.next() 7 times, save those elements in its list, and return the last one.

This would allow downstream code to use it as a list, but avoid unnecessarily instantiating a list for cases where list functionality was not needed, and avoid allocating memory for the entire list if only a few members ended up being requested.

It seems like a pretty easy one to write, but it also seems useful enough that it's likely that someone would have already made it available in a module.

+2  A: 
import itertools
class Indexable(object):
    def __init__(self,it):
        self.it=it
        self.already_computed=[]
    def __iter__(self):
        for elt in self.it:
            self.already_computed.append(elt)
            yield elt
    def __getitem__(self,index):
        try:
            max_idx=index.stop
        except AttributeError:
            max_idx=index
        n=max_idx-len(self.already_computed)+1
        if n>0:
            self.already_computed.extend(itertools.islice(self.it,n))
        return self.already_computed[index]      
unutbu
`list.extend` takes an arbitrary iterable as its argument, so you can write `.extend(list(itertools.islice(self.it, n)))` as `.extend(itertools.islice(self.it, n))`
Mike Graham
@Mike Graham: Thank you for this improvement
unutbu