На этом шаге мы рассмотрим некоторые возможности модуля itertools.
Вы хотите проитерировать по всем возможным комбинациям и перестановкам коллекции элементов.
Модуль itertools предоставляет три функции, подходящие для этой задачи. Первая, itertools.permutations(), принимает коллекцию элементов и создает последовательность кортежей со всеми возможными перестановками (то есть она перемешивает их во всех возможных конфигурациях). Например:
>>> items = ['a', 'b', 'c'] >>> from itertools import permutations >>> for p in permutations(items): print(p) ('a', 'b', 'c') ('a', 'c', 'b') ('b', 'a', 'c') ('b', 'c', 'a') ('c', 'a', 'b') ('c', 'b', 'a') >>>
Если вы хотите получить все возможные перестановки меньшей длины, то можете передать функции необязательный аргумент со значением длины. Например:
>>> for p in permutations(items, 2): print(p) ('a', 'b') ('a', 'c') ('b', 'a') ('b', 'c') ('c', 'a') ('c', 'b') >>>
Используйте itertools.combmatiom(), чтобы создать последовательность комбинаций элементов входной последовательности. Например:
>>> from itertools import combinations >>> for c in combinations(items, 3): print(c) ('a', 'b', 'c') >>> for c in combinations(items, 2): print(c) ('a', 'b') ('a', 'c') ('b', 'c') >>> for c in combinations(items, 1): print(c) ('a',) ('b',) ('c',) >>>
Для функции combinations() порядок элементов не имеет значения. Комбинацию ('a', 'b') она считает аналогичной ('b', 'a') - поэтому вторая в выводимых результатах отсутствует.
При создании комбинаций выбранные элементы удаляются из коллекции возможных кандидатов (то есть если 'а' уже выбран, он больше не будет рассматриваться). А функция itertools.combinations_with_replacement() выбирает один и тот же элемент более одного раза. Например:
>>> from itertools import combinations_with_replacement >>> for c in combinations_with_replacement(items, 3): print(c) ('a', 'a', 'a') ('a', 'a', 'b') ('a', 'a', 'c') ('a', 'b', 'b') ('a', 'b', 'c') ('a', 'c', 'c') ('b', 'b', 'b') ('b', 'b', 'c') ('b', 'c', 'c') ('c', 'c', 'c') >>>
Этот рецепт показывает лишь небольшую часть мощи модуля itertools. Хотя вы могли бы самостоятельно написать код, который выполняет перестановки и комбинации, это, вероятно, отняло бы у вас больше пары секунд времени. Когда вы сталкиваетесь с нетривиальными задачами в сфере итераций, обратитесь к itertools, это всегда окупается. Если задача распространенная, велик шанс того, что вы найдете готовое решение.
На следующем шаге мы рассмотрим итерирование по парам "индекс-значение" последовательности.