Итераторы можно применять вместо последовательности в операторе for
. Более того, внутренне оператор for
запрашивает от последовательности ее итератор. Объект файлового типа тоже (построчный) итератор, что позволяет обрабатывать большие файлы, не считывая их целиком в память.
Там, где требуется итератор, можно использовать последовательность.
Работа с итераторами рассматривается в разделе, посвященном функциональному программированию, так как итераторами удобно манипулировать именно в функциональном стиле.
Использовать итератор можно и «вручную». Любой объект, поддерживающий интерфейс итератора, имеет метод next()
, который при каждом вызове выдает очередное значение итератора. Если больше значений нет, возбуждается исключение StopIteration
. Для получения итератора по некоторому объекту необходимо прежде применить к этому объекту функцию iter()
(цикл for делает это автоматически).
В Python имеется модуль itertools
, который содержит набор функций, комбинируя которые, можно составлять достаточно сложные схемы обработки данных с помощью итераторов. Далее рассматриваются некоторые функции этого модуля.
Эта функция имеет два варианта использования. В первом она принимает всего один аргумент, который должен «уметь» предоставлять свой итератор. Во втором один из аргументов — функция без аргументов, другой — стоповое значение. Итератор вызывает указанную функцию до тех пор, пока та не возвратит стоповое значение. Второй вариант встречается много реже первого и обычно внутри метода класса, так как сложно порождать значения «на пустом месте»:
it1 = iter([1, 2, 3, 4, 5])
def forit(mystate=[]):
if len(mystate) < 3:
mystate.append(" ")
return " "
it2 = iter(forit, None)
print [x for x in it1]
print [x for x in it2]
Примечание:
Если функция не возвращает значения явно, она возвращает None
, что и использовано в примере выше.
Эта функция создает итератор, нумерующий элементы другого итератора. Результирующий итератор выдает кортежи, в которых первый элемент — номер (начиная с нуля), а второй — элемент исходной последовательности:
>>> print [x for x in enumerate("abcd")]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Эта функция, появившаяся в Python 2.4, позволяет создавать итератор, выполняющий сортировку:
>>> sorted('avdsdf')
['a', 'd', 'd', 'f', 's', 'v']
Далее рассматриваются функции модуля itertools
.
Функция itertools.chain()
Функция chain()
позволяет сделать итератор, состоящий из нескольких соединенных последовательно итераторов. Итераторы задаются в виде отдельных аргументов. Пример:
from itertools import chain
it1 = iter([1,2,3])
it2 = iter([8,9,0])
for i in chain(it1, it2):
print i,
даст в результате
1 2 3 8 9 0
Функция itertools.repeat()
Функция repeat()
строит итератор, повторяющий некоторый объект заданное количество раз:
for i in itertools.repeat(1, 4):
print i,
1 1 1 1
Функция itertools.count()
Бесконечный итератор, дающий целые числа, начиная с заданного:
for i in itertools.count(1):
print i,
if i > 100:
break
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
Функция itertools.cycle()
Можно бесконечно повторять и некоторую последовательность (или значения другого итератора) с помощью функции cycle()
:
tango = [1, 2, 3]
for i in itertools.cycle(tango):
print i,
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 ...
Функции itertools.imap(), itertools.starmap() и itertools.ifilter()
Аналогами map()
и filter()
в модуле itertools
являются imap()
и ifilter()
. Отличие imap()
от map()
в том, что вместо значения от преждевременно завершившихся итераторов объект None
не подставляется. Пример:
for i in map(lambda x, y: (x,y), [1,2], [1,2,3]):
print i,
(1, 1) (2, 2) (None, 3)
from itertools import imap
for i in imap(lambda x, y: (x,y), [1,2], [1,2,3]):
print i,
(1, 1) (2, 2)
Здесь следует заметить, что обычная функция map()
нормально воспринимает итераторы в любом сочетании с итерабельными (поддающимися итерациям) объектами:
Читать дальше
Конец ознакомительного отрывка
Купить книгу