Модуль itertools

определение
Библиотека описывает объекты итераторов для разных случаев
Бескончные итераторы
count - итератор равномерно распределенных значений. Указывается стартовый элемент и шаг.

cycle - итератор циклически возвращает элементы итерируемого объекта

repeat - итератор, который возвращает всегда один объект
count

from itertools import count

cnt = count(start=0, step=2)

for i in range(10):
    print(next(cnt))
cycle

from itertools import cycle

cyls = cycle([1, 2, 3])
print(next(cyls))  # 1
print(next(cyls))  # 2
print(next(cyls)) # 3
print(next(cyls))  # 1

repeat

from itertools import repeat

repearter = repeat('PY')
next(repearter)  # PY
next(repearter)  # PY
next(repearter)  # PY

list(repeat('PY', 2))

Конечные итераторы
accumulate() - итератор принимает два аргумента, итерируемую цель и функцию, которая будет выполняться при каждой итерации значения. Если функция не передана, добавление происходит по умолчанию.

chain() - эта функция используется для итерации по элементам, которые переданы в аргументы.

chain.from_iterable() - эта функция реализована так же, как chain(), но аргументом здесь является один любой итерируемый контейнер.

compress() - этот итератор выборочно выбирает значения из переданного контейнера в соответствии со значением логического списка, переданным вторым аргументом. Аргументы, соответствующие логическому значению true, печатаются, иначе все они пропускаются.

dropwhile() - итератор выводит элементы после элемента, который дает значение в функции выборки.

filterfalse() - итератор печатает значения, которые возвращают false для переданной функции.

groupby() - создаёт итератор по сгруппированным элементам переданного объекта.

islice() - этот итератор выборочно выводит значения, указанные в его итерируемом контейнере, переданном в качестве аргумента. Этот итератор принимает 4 аргумента: итерируемый контейнер, начальную позицию, конечную позицию и шаг.

pairwise() - возвращает итератор перекрывающих пары элементов последовательности

starmap()
- итератор принимает функцию и список кортежей в качестве аргумента и возвращает значение в соответствии с функцией из каждого кортежа списка.

takewhile() - итератор является противоположностью dropwhile(), он печатает значения до тех пор, пока функция не вернет false в первый раз.

tee() - cоздаёт несколько итераторов для одного итерируемого объекта.

zip_longest()
- итератор последовательно выводит значения итерируемых объектов. Если одна из итераций печатается полностью, оставшиеся значения заполняются значениями, присвоенными fillvalue.
accumulate

from itertools import accumulate
from operator import mul


print("Сумма после каждой итерации:")
print(list(accumulate([1, 4, 5, 7])))
# Вывод: [1, 5, 10, 17]


print("Умножение после каждой итерации:")
print(list(accumulate([1, 4, 5, 7], mul)))
# Вывод: [1, 4, 20, 140]
chain

from itertools import chain

print("Итерация по элементам списка:")
print(list(chain([1, 4, 5, 7], [1, 6, 5, 9], [8, 10, 5, 4])))

#Вывод: [1, 4, 5, 7, 1, 6, 5, 9, 8, 10, 5, 4]
compress

from itertools import compress

print("Вывод элементов, в индексе маски которого стоит значение True или 1:")
print(list(compress('GEEKSFORGEEKS', [1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0])))

#Вывод: ['G', 'F', 'G']
dropwhile

from itertools import dropwhile

print("Вывод значений после элемента, если функция возвращает false:")
print(list(dropwhile(lambda x: x % 2 == 0, [2, 4, 5, 7, 8])))

#Вывод: [5, 7, 8]
filterfalse

from itertools import filterfalse

print("Вывод значений, если функция возвращает false:")
print(list(filterfalse(lambda x: x % 2 == 0, [2, 4, 5, 7, 8])))

#Вывод нечетных элементов [5, 7]
groupby

from itertools import groupby


def grouper(item):
    """Будем использовать эту функцию для группировки сортировки."""
    return item['country']


data = [
    {'city': 'Москва', 'country': 'Россия'},
    {'city': 'Новосибирск', 'country': 'Россия'},
    {'city': 'Пекин', 'country': 'Китай'},
]

for key, group_items in groupby(data, key=grouper):
    print('Key: %s' % key)
    for item in group_items:
        print('Item: %s' % item)
islice

from itertools import islice

print("Выборочны значения списка:")
print(list(islice([2, 4, 5, 7, 8, 10, 20], 1, 6, 2)))

#Вывод [4, 7, 10]
pairwise

from itertools import pairwise

print("Выборочны значения списка:")
print(list(pairwise('ABCDEFG')))

#Вывод [('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'E'), ('E', 'F'), ('F', 'G')]

starmap

from itertools import starmap

li = [(1, 10, 5), (8, 4, 1), (5, 4, 9), (11, 10, 1)]
print("Возвращает минимальные значения из кортежей:")
print(list(starmap(min, li)))

#Вывод: [1, 1, 4, 1]
takewhile

from itertools import takewhile  

print("Выводит значения, пока функция не будет равна False:")
print(list(takewhile(lambda x : x % 2 == 0, [2, 4, 6, 7, 8, 10, 20])))

#Вывод [2, 4, 6]
tree

from itertools import tee

iter1, iter2, iter3 = tee([1, 2, 3], 3)

print(list(iter1))
print(list(iter2))
print(list(iter3))

# Вывод: [1, 2, 3]
# Вывод: [1, 2, 3]
# Вывод: [1, 2, 3]
sip_longest

from itertools import zip_longest

print("Вывод пар элементов из двух последовательностей: ")
print(*(zip_longest('GesoGes', 'ekfr', fillvalue ='_')))

#Вывод ('G', 'e') ('e', 'k') ('s', 'f') ('o', 'r') ('G', '_') ('e', '_') ('s', '_')
Комбинаторные итераторы
Рекурсивные генераторы, которые используются для упрощения написания комбинаторных конструкций: перестановки, комбинации и декартовы произведения.

product - этот инструмент вычисляет декартово произведение входных итераций. Позволяет вычислить произведение итерируемого объекта на самого себя. Результатом этой функции является кортеж в отсортированном порядке.

permutations - используется для генерации всех возможных перестановок итерируемого объекта . Все элементы считаются уникальными на основе их положения, а не их значений. Эта функция принимает итерируемый объект и размер группы (group_size).

combinations- этот итератор печатает все возможные комбинации (без замены) контейнера, переданного в аргументах, в указанном размере группы без повторений.

combinations_with_replacement - функция возвращает подпоследовательность длины n из элементов итерируемого объекта, где n — аргумент, длина последовательностей, сгенерированных функцией. Комбинации строятся из повторяющихся элементов.
product

from itertools import product

print("Декартово произведение с использованием повторения:")
print(list(product([1, 2], repeat=2)))
# Вывод: [(1, 1), (1, 2), (2, 1), (2, 2)]

print("Декартово произведение контейнеров:")
print(list(product(['geeks', 'for', 'geeks'], '2')))
# Вывод: [('geeks', '2'), ('for', '2'), ('geeks', '2')]
   
print("Декартово произведение контейнеров:")
print(list(product('AB', [3, 4])))
# Вывод: [('A', 3), ('A', 4), ('B', 3), ('B', 4)]
permutations

from itertools import permutations

print("Все перестановки списка:")
print(list(permutations([1, 'geeks'], 2)))
# Вывод: [(1, 'geeks'), ('geeks', 1)]

print("Все перестановки строки:")
print(list(permutations('AB')))
# Вывод: [('A', 'B'), ('B', 'A')]

print("Все перестановки контейнера:")
print(list(permutations(range(3), 2)))
# Вывод: [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
combinations

from itertools import combinations

print("Комбинация списка:")
print(list(combinations(['A', 2], 2)))
# Вывод: [('A', 2)]

print("Комбинация строк:")
print(list(combinations('ABC', 2)))
# Вывод: [('A', 'B'), ('A', 'C'), ('B', 'C')]

print("Комбинация списка через генератор:")
print(list(combinations(range(4), 3)))
# Вывод:[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
combinations_with_replacement

from itertools import combinations_with_replacement

print("Комбинация списка")
print(list(combinations_with_replacement(['A', 2], 2)))
# Вывод: [('A', 'A'), ('A', 2), (2, 2)]

print("Комбинация строк")
print(list(combinations_with_replacement("ABС", 2)))
# Вывод: [('A', 'A'), ('A', 'B'), ('A', 'С'), ('B', 'B'), ('B', 'С'), ('С', 'С')]

print("Комбинация списка через генератор")
print(list(combinations_with_replacement(range(4), 3)))
# Вывод: [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 2, 2), (0, 2, 3), (0, 3, 3), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 2), (1, 2, 3), (1, 3, 3), (2, 2, 2), (2, 2, 3), (2, 3, 3), (3, 3, 3)]