Способы создания итераторов

Итераторы — это специальные объекты, представляющие последовательный доступ к данным из контейнера. При этом немаловажную роль играет то, что память фактически не тратится, так как промежуточные данные выдаются по мере необходимости при запросе, поэтому фактически в памяти останутся только исходные данные и конечный результат, да и их можно читать и записывать, используя файл на диске.

Итератор удобно использовать вместе с последовательностью. Любой объект, поддерживающий интерфейс итератора, имеет метод next(), позволяющий переходить на следующую ступень вычисления. Чтобы получить итератор по объекту (например, по списку), к нему нужно применить функцию iter(). Кстати, уже упомянутый цикл for тоже задействует итератор, только без дополнительных танцев — все делается автоматически. Для обработки сложных наборов данных можно подключить стандартный модуль itertools.

Создадим простейший итератор вручную:

testIt = iter([1, 2, 3, 4, 5])
print [x for x in testIt]

Конечно, это простейшее использование цикла for, только записанное немного по-другому. «И что же тут нового?» — спросите вы. Да, в принципе, ничего, просто немного залезли глубже в структуру обработки последовательностей. Но теперь, как вам такое: функция iter() может принимать не только структуру данных, которая так запросто представляет свой итератор, но и два совсем других аргумента: функцию без аргументов и стоповое значение, на котором итерация остановится. Пример:

def getSimple(state=[]):
    if len(state) < 4:
        state.append(" ")
        return " " testIt2 = iter(getSimple, None)
    print [x for x in testIt2]

Пример основан на том, что в Python при отсутствии явного возвращения значения из функции возвращается значение None.

Предположим, что нам нужно сделать объект, который берет данные из строк очень большого файла. Данные нужны порциями, которые записаны в строках текстового файла, одна порция, одна строка. Обрабатывать нужно в цикле "for...in"

Создаем такой класс:

class SimpleIterator(object):

    def __init__(self,fname):
        self.fd = open(fname,'r')
    def __iter__(self):
        return self

    def next(self):
        l = self.fd.readline()
            if l != '':
12             l = l.rstrip('\n')
13             num = int(l)
14             return num*2
15         raise StopIteration

Last updated

Was this helpful?