|
|
Комбинаторные функции модуля itertools
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
Следующая
функция accumulate() модуля itertools позволяет
последовательно обрабатывать значения итерируемых объектов, формируя множество
выходных значений на каждом шаге своей работы. Проще всего понять суть работы
функции accumulate() на конкретных
примерах.
Общий синтаксис
функции следующий:
itertools.accumulate(iterable[,
func])
- iterable –
последовательность элементов (например, список чисел);
- func (не
обязательный аргумент) – бинарная операция, применяемая к элементам
последовательно (по умолчанию сложение).
Допустим, у нас
в программе имеется следующий список чисел:
digs = [1, 2, 3, 4, 5, 6]
Тогда, применяя
к нему функцию accumulate():
res_it = accumulate(digs) # итератор для формирования выходных значений
res = list(res_it) # список с результатами вычислений
получим результат:
res: [1, 3, 6, 10,
15, 21]
Видим, что на
каждом шаге выполнялось суммирование всех предыдущих значений списка. Первое
значение 1 остается как есть без изменений.
Работа функции accumulate()
очень похожа на ранее рассмотренную функцию reduce() с той лишь
разницей, что reduce() возвращает только
конечный результат:
res_rd = functools.reduce(lambda a, b: a + b, digs) # 21
а функция accumulate()
выдает и все промежуточные вычисления.
По аналогии с reduce() в функции accumulate()
вторым аргументом можно указать ссылку на любую функцию с двумя аргументами,
возвращающий определенный результат. Например:
res_it = accumulate(digs, lambda a, b: a * b) # [1, 2, 6, 24, 120, 720]
res_it = accumulate(digs, lambda a, b: a if a < b else b) # [1, 1, 1, 1, 1, 1]
s = "python"
res_it = accumulate(s) # ['p', 'py', 'pyt', 'pyth', 'pytho', 'python']
res_it = accumulate(s, lambda a, b: a + b + a) # ['p', 'pyp', 'pyptpyp', ...]
Функция product()
Следующая
функция product() формирует,
так называемое, декартовое произведение на основе итерируемых последовательностей.
Как это работает? И что из себя представляет декартовое произведение?
Давайте
представим, что у нас есть две коллекции:
alpha = ('A', 'B', 'C')
numbers = [1, 2, 3, 4]
Тогда их
декартово произведение – множество всех сочетаний элементов первой и второй
коллекций:
Именно такой
результат формирует функция product() со следующим синтаксисом:
product(*iterables,
repeat=1)
Применим ее к
последовательностям alpha и numbers:
res_it = product(alpha, numbers)
res = list(res_it)
Получим
результат в виде следующего списка:
[('A', 1), ('A',
2), ('A', 3), ('A', 4), ('B', 1), ('B', 2), ('B', 3), ('B', 4), ('C', 1), ('C',
2), ('C', 3), ('C', 4)]
Последний
аргумент repeat=1 определяет
число повторений для каждой последовательности. Его удобно использовать,
например, когда нужно вычислить декартовое произведение итерируемого объекта с
самим собой:
res_it = product(alpha, repeat=2)
res = list(res_it)
Увидим
результат:
[('A', 'A'),
('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('C', 'A'), ('C',
'B'), ('C', 'C')]
Конечно, вместо
чисел списка numbers можно передать
аналогичный итерируемый объект range(). Функция product() обрабатывает
любые итерируемые данные:
res_it = product(alpha, range(1, 5))
Таким образом, функция
product() полезна,
когда необходимо перебрать всевозможные комбинации значений из разных
последовательностей. Она применяется в таких сценариях, как обработка данных,
создание тестов с разными параметрами, работа с алгоритмами машинного обучения
и многих других.
Функция permutations()
Следующая функция
permutations(iterable,
r=None)
возвращает
генератор всех возможных перестановок заданной длины r, составленных из
элементов входного итерируемого объекта (iterable). Если длина r не указана,
используется полная длина входного итерируемого объекта.
Например, если
этой функции передать указать строку:
res_it = permutations('ABC')
res = list(res_it)
то получим
кортежи из всех возможных перестановок:
[('A', 'B',
'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C',
'B', 'A')]
Причем для
коллекции размера N количество возможных перестановок длиной k определяется
выражением:
Вот еще
несколько примеров работы функции permutations():
res_it = permutations([1, 2, 3, 4], 2)
# [(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)]
colors = ('green', 'red', 'yellow')
res_it = permutations(colors, 2)
# [('green', 'red'), ('green', 'yellow'), ('red', 'green'), ('red', 'yellow'), ('yellow', 'green'), ('yellow', 'red')]
Функция permutations() может быть
использована в следующих задачах:
- генерация
уникальных паролей/комбинаций символов;
- анализ маршрутов
в логистике (например, расчет оптимального пути проезда между несколькими
пунктами назначения);
- работа с
различными комбинациями объектов (математические задачи, шахматные партии и
т.п.).
Функция combinations()
Последняя
функция, которую мы рассмотрим на этом занятии – это функция combinations(), которая
имеет следующий синтаксис:
itertools.combinations(iterable,
r)
Она предназначена
для генерации всех возможных комбинаций фиксированной длины из заданного набора
элементов:
- комбинации
формируются без учета порядка: (A, B) и (B, A) считаются одной и той же
комбинацией;
- повторение
одного и того же элемента невозможно внутри одной комбинации;
- размер
возвращаемых комбинаций равен значению второго аргумента r.
В отличие от
функции permutations(), которой важен набор элементов с учетом их порядка.
Давайте сравним
работу обеих функций combinations() и permutations() для
формирования перестановок пар чисел последовательности digits:
digits = [1, 2, 3, 4]
res_it = combinations(digits, 2)
res_it_per = permutations(digits, 2)
res = list(res_it) # [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
res2 = list(res_it_per) # [(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)]
Как видите,
функция permutations() дополнительно
выдает варианты с разными расстановками одних и тех же чисел, например: (1, 2)
и (2, 1). Тогда как функция combinations() формирует
только варианты с уникальными значениями без учета их взаимного расположения.
Во всем остальном функция combinations() работает так
же, как и функция permutations().
Функция combinations() может быть
использована в следующих задачах:
- создание
всевозможных группировок объектов (например, выбор игроков команды из общего
состава участников);
- решение
комбинаторных задач, где важно учитывать лишь присутствие элемента, а не порядок;
- генерация наборов
вариантов решений, например, для формирования меню блюд, сочетания продуктов и
т.п.
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
|