Модуль Itertools в Python – простое и краткое пособие

Данная статья будет посвящена модулю Itertiiols стандартной библиотеки Python. В ней мы расскажем как при помощи данного модуля получать бесконечные и комбинаторные итераторы.

Также мы еще раз узнаем как работают итераторы в Python.

Итак, давайте приступим к изучению модуля Itertools.

Что такое модуль Itertools?

Модуль Itertools стандартной библиотеки Python предназначен для создания эффективных и удобных итераторов.

Некоторые из них бесконечны, некоторые нет, а некоторые имеют комбинаторную природу.

Наряду с этим мы изучим итераторы, завершающиеся кратчайшей входной последовательностью.

Сначала давайте обсудим бесконечные итераторы.

Бесконечные итераторы в Python

Некоторые функции модуля Itertools способны генерировать бесконечные итераторы и в этом разделе мы их изучим.

Функция count([start=0, step=1])

Данная функция может принимать два аргумента: start (начало) и step (шаг). После этого она возвращает последовательность начиная с значения start с интервалом step.

from itertools import count

for i in count(10,2):
        print(i)
        if i>25: break

Результат:

10
12
14
16
18
20
22
24
26

А вот функция count() только с одним аргументом:

for i in count(2):
         print(i)

Результат:

2
3
4
5
6
7
Traceback (most recent call last):File “<pyshell#166>”, line 2, in <module>
print(i)
KeyboardInterrupt

Здесь был использован шаг по умолчанию равный 1. А если использовать функцию count() без аргументов, старт последовательности начинается с 0 и с тем шагом 1.

for i in count():
        print(i)

Результат:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Traceback (most recent call last):File “<pyshell#169>”, line 2, in <module>
print(i)
KeyboardInterrupt

Функция cycle(iterable)

Функция cycle() создает итератор из элементов итерируемой последовательности. Как только элементы итерируемой последовательности заканчиваются, данная функция начинает возвращать их заново. И это повторяется до бесконечности.

from itertools import cycle

for i in cycle(['red','green','blue']):
            print(i)

Результат:

red
green
blue
red
green
blue
red
green
blue
red
green
blue
red
green
blue
Traceback (most recent call last):File “<pyshell#174>”, line 2, in <module>
print(i)
<KeyboardInterrupt

Функция cycle() может принимать любые итерируемые последовательности.

Функция repeat(elem [,n])

Данная функция создает итератор, где аргумент elem будет повторяться n раз, либо бесконечное количество раз, если аргумент n не будет задан.

from itertools import repeat

for i in repeat(‘Red’,3):
         print(i)

Результат:

Red
Red
Red
for  i in repeat('Red'):
          print(i)

Результат:

Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Traceback (most recent call last):File “<pyshell#181>”, line 2, in <module>
print(i)
KeyboardInterrupt

Комбинаторные итераторы в Python

Комбинаторика — раздел математики о вычислении количества различных комбинаций каких-либо элементов. Давайте поговорим о комбинаторных итераторах.

Функция product(*iterables, repeat=1)

Данная функция возвращает декартово произведение входных итерируемых последовательностей. Что эквивалентно вложенным циклам.

for i in product([1,2,3],[4,5,6]):
            print(i)

Результат:

(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)

Это эквивалентно следующему коду со вложенными циклами.

for i in ((i,j) for i in [1,2,3] for j in [4,5,6]):
            print(i)

Результат:

(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)

Рассмотрим ещё пару примеров.

for i in product('AB','CD','EF'):
           print(i)

Результат:

(‘A’, ‘C’, ‘E’)
(‘A’, ‘C’, ‘F’)
(‘A’, ‘D’, ‘E’)
(‘A’, ‘D’, ‘F’)
(‘B’, ‘C’, ‘E’)
(‘B’, ‘C’, ‘F’)
(‘B’, ‘D’, ‘E’)
(‘B’, ‘D’, ‘F’)

В следующем примере аргумент repeat будет равен двум и крайне правый элемент будет каждый раз чередоваться.

for i in product('AB','CD',repeat=2):
           print(i)

Результат:

(‘A’, ‘C’, ‘A’, ‘C’)
(‘A’, ‘C’, ‘A’, ‘D’)
(‘A’, ‘C’, ‘B’, ‘C’)
(‘A’, ‘C’, ‘B’, ‘D’)
(‘A’, ‘D’, ‘A’, ‘C’)
(‘A’, ‘D’, ‘A’, ‘D’)
(‘A’, ‘D’, ‘B’, ‘C’)
(‘A’, ‘D’, ‘B’, ‘D’)
(‘B’, ‘C’, ‘A’, ‘C’)
(‘B’, ‘C’, ‘A’, ‘D’)
(‘B’, ‘C’, ‘B’, ‘C’)
(‘B’, ‘C’, ‘B’, ‘D’)
(‘B’, ‘D’, ‘A’, ‘C’)
(‘B’, ‘D’, ‘A’, ‘D’)
(‘B’, ‘D’, ‘B’, ‘C’)
(‘B’, ‘D’, ‘B’, ‘D’)

Функция permutations(iterable, r=None)

Функция permutations() возвращает перестановку длиной r переданной в нее итерируемой последовательности элементов.

Она будет генерировать все возможные перестановки элементов без повторений в лексикографическом порядке.

from itertools import permutations

for i in permutations('ABCD'):
           print(i)

Результат:

(‘A’, ‘B’, ‘C’, ‘D’)
(‘A’, ‘B’, ‘D’, ‘C’)
(‘A’, ‘C’, ‘B’, ‘D’)
(‘A’, ‘C’, ‘D’, ‘B’)
(‘A’, ‘D’, ‘B’, ‘C’)
(‘A’, ‘D’, ‘C’, ‘B’)
(‘B’, ‘A’, ‘C’, ‘D’)
(‘B’, ‘A’, ‘D’, ‘C’)
(‘B’, ‘C’, ‘A’, ‘D’)
(‘B’, ‘C’, ‘D’, ‘A’)
(‘B’, ‘D’, ‘A’, ‘C’)
(‘B’, ‘D’, ‘C’, ‘A’)
(‘C’, ‘A’, ‘B’, ‘D’)
(‘C’, ‘A’, ‘D’, ‘B’)
(‘C’, ‘B’, ‘A’, ‘D’)
(‘C’, ‘B’, ‘D’, ‘A’)
(‘C’, ‘D’, ‘A’, ‘B’)
(‘C’, ‘D’, ‘B’, ‘A’)
(‘D’, ‘A’, ‘B’, ‘C’)
(‘D’, ‘A’, ‘C’, ‘B’)
(‘D’, ‘B’, ‘A’, ‘C’)
(‘D’, ‘B’, ‘C’, ‘A’)
(‘D’, ‘C’, ‘A’, ‘B’)
(‘D’, ‘C’, ‘B’, ‘A’)

Здесь мы не передавали в функцию второй аргумент, поэтому она выводила кортежи длиной 4, что соответствует длине итерируемого объекта.

Теперь давайте передадим во второй аргумент значение 3:

for i in permutations('ABCD',3):
           print(i)

Результат:

(‘A’, ‘B’, ‘C’)
(‘A’, ‘B’, ‘D’)
(‘A’, ‘C’, ‘B’)
(‘A’, ‘C’, ‘D’)
(‘A’, ‘D’, ‘B’)
(‘A’, ‘D’, ‘C’)
(‘B’, ‘A’, ‘C’)
(‘B’, ‘A’, ‘D’)
(‘B’, ‘C’, ‘A’)
(‘B’, ‘C’, ‘D’)
(‘B’, ‘D’, ‘A’)
(‘B’, ‘D’, ‘C’)
(‘C’, ‘A’, ‘B’)
(‘C’, ‘A’, ‘D’)
(‘C’, ‘B’, ‘A’)
(‘C’, ‘B’, ‘D’)
(‘C’, ‘D’, ‘A’)
(‘C’, ‘D’, ‘B’)
(‘D’, ‘A’, ‘B’)
(‘D’, ‘A’, ‘C’)
(‘D’, ‘B’, ‘A’)
(‘D’, ‘B’, ‘C’)
(‘D’, ‘C’, ‘A’)
(‘D’, ‘C’, ‘B’)

Функция combinations(iterable, r)

Данная функция возвращает все возможные подпоследовательности (сочетания) длины r переданной в нее итерируемой последовательности.

from itertools import combinations

for i in combinations('ABCD',2):
          print(i)

Результат:

(‘A’, ‘B’)
(‘A’, ‘C’)
(‘A’, ‘D’)
(‘B’, ‘C’)
(‘B’, ‘D’)
(‘C’, ‘D’)

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

Рассмотрим еще один пример:

for i in combinations(range(4),3):
                print(i)

Результат:

(0, 1, 2)
(0, 1, 3)
(0, 2, 3)
(1, 2, 3)

Функция combinations_with_replacement(iterable, r)

Данная функция возвращает все возможные подпоследовательности (сочетания) с повторениями длины r переданной в нее итерируемой последовательности. То есть отдельные элементы подпоследовательности могут в ней повторяться.

from itertools import combinations_with_replacement as cwr

for i in cwr('ABCD',2):
         print(i)

Результат:

(‘A’, ‘A’)
(‘A’, ‘B’)
(‘A’, ‘C’)
(‘A’, ‘D’)
(‘B’, ‘B’)
(‘B’, ‘C’)
(‘B’, ‘D’)
(‘C’, ‘C’)
(‘C’, ‘D’)
(‘D’, ‘D’)

Итераторы, завершающиеся на кратчайшей входной последовательности

Функция accumulate(iterable [,func])

Данная функция создаёт итератор с накопленными суммами или результатами другой функции, переданной в качестве второго аргумента.

from itertools import accumulate

for i in accumulate([0,1,0,1,1,2,3,5]):
         print(i)

Результат:

1
1
2
3
5
8
13

Нетрудно заметить, что это последовательность Фибоначчи.

Рассмотрим еще пару примеров.

import operator

for i in accumulate([1,2,3,4,5],operator.mul):
         print(i)

Результат:

1
2
6
24
120
for i in accumulate([2,1,4,3,5],max):
          print(i)

Результат:

2
2
4
4
5

Функция chain(*iterables)

Функция chain() создает итератор из входящих итерируемых последовательностей, соединяя их по порядку. По мере окончания одной итерируемой последовательности, функция переходит к следующей и так далее, до того как они все исчерпаются.

from itertools import chain

for i in chain('Hello','World','Bye'):
            print(i)

Результат:

H
e
l
l
o
W
o
r
l
d
B
y
e

Функция chain.from_iterable(iterable)

Это альтернативная конструкция предыдущей функции chain(). Она принимает один аргумент в виде списка или кортежа итерируемых последовательностей и лениво их вычисляет.

for i in chain.from_iterable(['Hello','World','Bye']):
           print(i)

Результат:

H
e
l
l
o
W
o
r
l
d
B
y
e

Для работы данной функции ничего дополнительно импортировать не требуется.

Функция compress(data, selectors)

Данная функция создает итератор из отфильтрованных элементов аргумента data. Фильтрация происходит на основании того, вычисляется ли элемент из аргумента selector как True или False.

from itertools import compress

for i in compress('ABCDEF',[1,0,1,True,0,' ']):
          print(i)

Результат:

A
C
D
F

Функция dropwhile(predicate,iterable)

Пока значение аргумента predicate равно True, элементы из аргумента iterable отбрасываются. Как только значение predicate становиться False, элементы из аргумента iterable (любая итерируемая последовательность) начинают возвращаться.

from itertools import dropwhile

for i in dropwhile(lambda x : x < 7, [1,2,7,9,5,3,2,9]):
            print(i)

Результат:

7
9
5
3
2
9

Функция filterfalse(predicate, iterable)

Данная функция создает итератор, который отфильтровывает из итерируемой последовательности iterable (второй аргумент функции) те элементы, для которых значения аргумента predicate равно True.

from itertools import filterfalse

for i in filterfalse(lambda x : x < 7, [1,2,7,9,5,3,2,9]):
            print(i)

Результат:

7
9
9
for i in filterfalse(lambda x : x % 2, [1,2,7,9,5,3,2,9]):
            print(i)

Результат:

2
2

Функция groupby(iterable, key=None)

Данная функция осуществляет группировку переданной в нее итерируемой последовательности согласно заданной в параметре key функции группировки. Если этот параметр не задан, то элементы итерируемой последовательности будут сгруппированы в том порядке, в котором они идут.

from itertools import groupby

for i,j in groupby('AAAAABBCCCCCDDDCCCBBA'):
            print(list(j))

Результат:

[‘A’, ‘A’, ‘A’, ‘A’, ‘A’]
[‘B’, ‘B’]
[‘C’, ‘C’, ‘C’, ‘C’, ‘C’]
[‘D’, ‘D’, ‘D’]
[‘C’, ‘C’, ‘C’]
[‘B’, ‘B’]
[‘A’]

Функция islice(iterable, start, stop [,step])

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

from itertools import islice

for i in islice([1,2,3,4,5], 2):
            print(i)

Результат:

1
2
for i in islice([1,2,3,4,5],2,5):
            print(i)

Результат:

3
4
5
for i in islice([1,2,3,4,5],0,5,2):
            print(i)

Результат:

1
3
5

Функция starmap(function, iterable)

Данная функция создает итератор, который вычисляет функция function, используя аргументы в виде кортежа из итерируемого объекта iterable.

from itertools import starmap

for i in starmap(operator.sub,[(2,1),(7,3),(15,10)]):
         print(i)

Результат:

1
4
5

Функция takewhile(predicate, iterable)

Пока значение аргумента predicate равно False, элементы из аргумента iterable отбрасываются. Как только значение predicate становиться True, элементы из аргумента iterable (любая итерируемая последовательность) начинают возвращаться. То же самое, только наоборот (если поменять местами True и False) , делает функция dropwhile().

from itertools import takewhile

for i in takewhile(lambda x:x<7,[1,2,7,9,5,3,2,9]):
            print(i)

Результат:

1
2

Функция tee(iterable, n=2)

Данная функция создает n независимых итераторов из одной итерируемой последовательности.

from itertools import tee

for i in tee([1,2,3,4,5,6,7], 3):
            for j in i: print(j)
            print()

Результат:

1
2
3
4
5
6
7

1
2
3
4
5
6
7

1
2
3
4
5
6
7

Функция zip_longest(*iterables, fillvalue=None)

Данная функция создает итератор, агрегируя элементы из переданных в нее итерируемых объектов. Параметр fillvalue определяет чем заполнять итерируемые последовательности, которые короче остальных.

from itertools import zip_longest

for i in zip_longest('ABC','12345',fillvalue='*'):
            print(i)

Результат:

(‘A’, ‘1’)
(‘B’, ‘2’)
(‘C’, ‘3’)
(‘*’, ‘4’)
(‘*’, ‘5’)
for i in zip_longest('ABC','12345','Hello',fillvalue='*'):
            print(i)

Результат:

(‘A’, ‘1’, ‘H’)
(‘B’, ‘2’, ‘e’)
(‘C’, ‘3’, ‘l’)
(‘*’, ‘4’, ‘l’)
(‘*’, ‘5’, ‘o’)

Итак, это было все, что мы хотели вам рассказать о модуле Itertools в Python. Надеемся, вам все понравилось!

Вопросы по данному модулю из собеседований

  1. Что такое модуль itertools в Python?
  2. Какие задачи можно решать при помощи модуля itertools в Python?
  3. Входит ли модуль itertools в стандартную библиотеку Python?
  4. Какие есть преимущества и ограничения при использовании модуля itertools?
  5. Как данный модуль работает в Python?

Заключение

В данной статье по модулю Itertools в Python мы обсудили три вида итераторов, создаваемых функциями из модуля itertools.

Это бесконечные итераторы, комбинаторные итераторы и итераторы, заканчивающиеся кратчайшей входной последовательностью.

Перевод статьи Python Itertools Tutorial – A Quick and Easy Guide.

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Scroll to Top