print [x for x in it1]
print [x for x in it2]
Если функция не возвращает значения явно, она возвращает None
, что и использовано в примере выше.
Функция enumerate()
Эта функция создает итератор, нумерующий элементы другого итератора. Результирующий итератор выдает кортежи, в которых первый элемент — номер (начиная с нуля), а второй — элемент исходной последовательности:
>>> print [x for x in enumerate("abcd")]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Функция sorted()
Эта функция, появившаяся в 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()
нормально воспринимает итераторы в любом сочетании с итерабельными (поддающимися итерациям) объектами:
for i in map(lambda x, y: (x,y), iter([1,2]), [1,2,3]):
print i,
(1, 1) (2, 2) (None, 3)
Функция itertools.starmap()
подобна itertools.imap()
, но имеет всего два аргумента. Второй аргумент — последовательность кортежей, каждый кортеж которой задает набор параметров для функции (первого аргумента):
>>> from itertools import starmap
>>> for i in starmap(lambda x, y: str(x) + y, [(1,'a'), (2,'b')]):
... print i,
...
1a 2b
Функция ifilter()
работает как filter()
. Кроме того, в модуле itertools
есть функция ifilterfalse()
, которая как бы добавляет отрицание к значению функции:
for i in ifilterfalse(lambda x: x > 0, [1, -2, 3, -3]):
print i,
-2 –3
Функции itertools.takewhile() и itertools.dropwhile()
Некоторую новизну вносит другой вид фильтра: takewhile()
и его «отрицательный» аналог dropwhile()
. Следующий пример поясняет их принцип действия:
for i in takewhile(lambda x: x > 0, [1, -2, 3, -3]):
print i,
print
for i in dropwhile(lambda x: x > 0, [1, -2, 3, -3]):
print i,
1
-2 3 -3
Таким образом, takewhile()
дает значения, пока условие истинно, а остальные значения даже не берет из итератора (именно не берет, а не высасывает все до конца!). И, наоборот, dropwhile()
ничего не выдает, пока выполняется условие, зато потом выдает все без остатка.
Функция itertools.izip()
Функция izip()
аналогична встроенной zip()
, но не тратит много памяти на построение списка кортежей, так как итератор выдает их строго по требованию.
Функция itertools.groupby()
Эта функция дебютировала в Python 2.4. Функция принимает два аргумента: итератор (обязательный) и необязательный аргумент — функцию, дающую значение ключа: groupby(iterable[, func])
. Результатом является итератор, который возвращает двухэлементный кортеж: ключ и итератор по идущим подряд элементам с этим ключом. Если второй аргумент опущен, элемент итератора сам является ключом. В следующем примере группируются идущие подряд положительные и отрицательные элементы:
import itertools, math
lst = map(lambda x: math.sin(x*.4), range(30))
for k, i in itertools.groupby(lst, lambda x: x > 0):
print k, list(i)
Функция itertools.tee()
Эта функция тоже появилась в Python 2.4. Она позволяет клонировать итераторы. Первый аргумент — итератор, подлежащий клонированию. Второй (N
) — количество необходимых копий. Функция возвращает кортеж из N
итераторов. По умолчанию N=2
. Функция имеет смысл, только если итераторы задействованы более или менее параллельно. В противном случае выгоднее превратить исходный итератор в список.
Собственный итератор