Рассмотрим модуль itertools. Модуль содержит функции, которые позволяют выполнять итерации по данным различными способами. Все функции в модуле itertools возвращают итераторы, которые можно использовать в инструкции for и в других функциях, где применяются итераторы, например в функциях-генераторах и в выражениях-генераторах. Многие функции работают как фильтры. Их удобно использовать для очистки данных. Благодаря этим функциям вы можете работать с текстом и числами. Рано или поздно вам придётся сталкиваться со сложными итерациями. Выводить данные в простой последовательности 1,2,3,4 - это простая задача. Когда нужно вывести непростой порядок чисел 1,2,3,1,2,3,1,2,3, то модуль легко поможет. Конечно, найдутся умельцы которые начнут описывать существующие функции при помощи циклов. Этот путь лишняя трата времени и многократное увеличение кода. Итак, начнём.
Тут функция accumulate на каждой итерации возвращает сумму предыдущих элементов последовательности. Я не знаю когда это применяется.
#!/usr/bin/python3
import itertools
#itertools.accumulate(iterable) - аккумулирует суммы.
arr = itertools.accumulate([1,2,3,4,5])
print(list(arr))
'''
вывод:
[1, 3, 6, 10, 15]
'''
Функция combinations создает итератор, который возвращает все возможные последовательности из заданных элементов. Элементы в возвращаемых последовательностях располагаются в том же порядке, в каком они встречаются в исходном объекте. Функция combinations позволяет перебирать все комбинации. Она работает как с числами, так и со строками.
arr = itertools.combinations('ABC', 2)
print(list(arr))
'''
вывод:
[('A', 'B'), ('A', 'C'), ('B', 'C')]
'''
itertools.combinations_with_replacement(<Последовательность>, <Количество комбинации>). Создает итератор, который возвращает кортеж, содержащий комбинацию из указанного количества элементов. Если <Количество комбинации> будет больше количества элементов в <Последовательности>, то будет слишком много дублей одного символа.
arr = itertools.combinations_with_replacement('ABC', 3)
print(list(arr))
'''
вывод:
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
'''
itertools.compress(<Фильтруемая последовательность>, <Последовательность логических значений>). Функция производит фильтрацию последовательности, указанной в первом параметре. Элемент возвращается, только если соответствующий элемент (с таким же индексом) из второй последовательности равен 1 (истина). Сравнение заканчивается, когда достигнут конец одной из последовательностей. Вы можете сделать игру как "Поле чудес". Открывается первая буква слова )
'''
0 - не показываем
1 - показываем
'''
arr = itertools.compress('абвгде', [1,1,1,0,0,1])
print(list(arr))
'''
вывод:
['а', 'б', 'в', 'е']
'''
itertools.count(start=0, step=1). Функция создает итератор, который воспроизводит упорядоченную и непрерывную последовательность целых чисел, начиная с start. Если аргумент start опущен, в качестве первого значения возвращается число 0. Обратите внимание, что этот итератор не поддерживает длинные целые числа. Изюминка этой функции в том, что можно делать шаг для итерации. Вам не нужно как в цикле for делать i % 2 == 0 и вставлять различные условия.
'''
цикл for с перескакиванием
первый параметр - начало отчёта
второй параметр - шаг
'''
for i in itertools.count(0, 3):
if i > 20:
break
print(i)
'''
вывод:
0
3
6
9
12
15
18
'''
itertools.cycle(iterable). Функция создает итератор, который в цикле многократно выполняет обход элементов в объекте iterable. Элементы циклично повторяются. Вы можете сделать последовательности: 121212, 123123123, 01010101. Вы должны помнить, что любой цикл должен быть остановлен условием. Сразу пишите условие внутри цикла и итератор q.
q=0
for i in itertools.cycle([1, 2, 3]):
print(i)
if q > 10:
break
q += 1
'''
вывод:
1
2
3
1
2
3
1
2
3
1
2
3
'''
itertools.filterfalse(<Функция>, <Последовательность>). Функция возвращает объект итератор, который в каждой итерации возвращает элемент последовательности, для которой функция, указанная в первом параметре, вернет значение False. Если в первом параметре вместо названия функции указать значение None, то каждый элемент последовательности будет проверен на соответствие значению False. Если элемент в логическом контексте возвращает значение True, то он не войдёт в возвращаемый результат. Одним словом, если условие соблюдается, то элемент удаляется. Функция идеально подходит для фильтра. Вы можете одним махом почистить список от ненужных значений.
def func(x):
return x > 3
arr = list(itertools.filterfalse(func, [4, 5, 6, 2, 3, 1, 0]))
print(arr)
'''
вывод:
[2, 3, 1, 0]
'''
itertools.permutations(<Последовательность>). Тут показан генератор списка Python. В итоге перебираются все комбинации символов из <Последовательности>. В каждую комбинацию символов вставляется разделитель. Сделать нечто подобное при помощи цикла - это довольно трудоёмкое занятие.
# можете использовать пустоту вместо разделителя
arr = [":".join(i) for i in itertools.permutations('aбвг')]
print(arr)
'''
вывод:
'a:б:в:г', 'a:б:г:в', 'a:в:б:г', 'a:в:г:б', 'a:г:б:в', 'a:г:в:б', 'б:a:в:г',\
'б:a:г:в', 'б:в:a:г', 'б:в:г:a', 'б:г:a:в', 'б:г:в:a', 'в:a:б:г', 'в:a:г:б',\
'в:б:a:г', 'в:б:г:a', 'в:г:a:б', 'в:г:б:a', 'г:a:б:в', 'г:a:в:б', 'г:б:a:в',\
'г:б:в:a', 'г:в:a:б', 'г:в:б:a']
'''
itertools.product(<Последовательность1>, <Последовательность2>, ...[, repeat=1]). На каждой итерации возвращает кортеж, содержащий комбинацию из элементов одной или нескольких последовательностей. Обратите внимание на repeat (повтор). Изменение этого значения влияет на длину кортежа. В примере ниже длина каждого кортежа 2 элемента.
arr = list(itertools.product('aбв', repeat=2))
print(arr)
'''
вывод:
[('a', 'a'), ('a', 'б'), ('a', 'в'), ('б', 'a'), ('б', 'б'), ('б', 'в'), \
('в', 'a'), ('в', 'б'), ('в', 'в')]
'''
itertools.starmap(<Функция>, <Последовательность>). Передает значение в функцию и возвращает результат ее выполнения. Обратите внимание на то, что каждый элемент должен быть последовательностью. При передаче в функцию производится распаковка последовательности. Иными словами, в функцию передаются отдельные элементы последовательности, а не последовательность целиком. Каждый маленький кортеж или список обрабатываются функцией funcFilter1 и возвращается результат в виде суммы всех элементов. Возвращается объект starmap и этот объект нужно перевести в список при помощи функции list.
def funcFilter1(x, y):
return x + y
arr = list(itertools.starmap(funcFilter1, [(1,2), [3,4], [5,6]]))
print(arr)
'''
вывод:
[3, 7, 11]
'''
itertools.takewhile(<Функция>, <Последовательность>). Функция takewhile возвращает итератор, в каждой итерации возвращает элемент последовательности, пока не встретится элемент, для которой функция, указанная в первом параметре вернет значение False. Одним словом, все элементы, которые соответствуют условию функции funcFilter2 будет сохранены, а другие элементы не соответствующие условию будут удалены.
def funcFilter2(x):
return x > 3
arr = list(itertools.takewhile(funcFilter2, [4, 5, 6, 0, 7, 2, 3]))
print(arr)
'''
вывод:
[4, 5, 6]
'''
itertools.zip_longest(<Последовательность1> [ , ... <ПоследовательностьN>] [ , fillvalue=None]). На каждой итерации возвращает кортеж, содержащий элементы последовательностей, которые расположены на одинаковом смещении.
arr = list(itertools.zip_longest((1,2,3,4,5), [6,7,8,9]))
print(list(arr))
'''
вывод:
[(1, 6), (2, 7), (3, 8), (4, 9), (5, None)]
'''
Если последовательности имеют разное количество элементов, то вместо отсутствующего элемента вставляется объект, указанный в параметре fillvalue. fillvalue - может принять любое значение. Посмотрите на пример.
arr = list(itertools.zip_longest((1,2,3,4,5), [6,7,8,9], fillvalue='empty'))
print(list(arr))
'''
вывод:
[(1, 6), (2, 7), (3, 8), (4, 9), (5, 'empty')]
'''