2010-05-25 5 views
3

Я хотел бы знать, есть ли класс, доступный либо в стандартной библиотеке, либо в pypi, что соответствует этому описанию.just-in-time list

Конструктор будет использовать итератор.

Он будет реализовывать протокол контейнера (то есть __getitem__, __len__ и т. Д.), Чтобы работали срезы, длина и т. Д. При этом он будет перебирать и сохранять только достаточные значения из аргумента конструктора, чтобы обеспечить любую запрашиваемую информацию.

Так что если запрошен jitlist [6], он будет называть self.source.next() 7 раз, сохраните эти элементы в своем списке и верните последний.

Это позволит использовать код ниже по потоку, чтобы использовать его в качестве списка, но избегать ненужного создания списка для случаев, когда функции списка не нужны, и избегать выделения памяти для всего списка, если только запрашивается несколько членов.

Кажется, довольно легко написать, но это также кажется достаточно полезным, что вполне вероятно, что кто-то уже сделал его доступным в модуле.

+1

Как бы это реализовать '__len__', не итерируя сначала источник? – balpha

+0

Он будет перебирать источник в ответ на '__len__'. – intuited

ответ

2
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]  
+0

'list.extend' принимает произвольный итеративный аргумент, поэтому вы можете написать' .extend (list (itertools.islice (self.it, n))) 'as' .extend (itertools.islice (self.it, n)) ' –

+0

@ Майк Грэм: Спасибо за это улучшение – unutbu

Смежные вопросы