- Что такое itertools?
- Бесконечная итерация
- count
- cycle
- repeat
- Комбинация значений
- combinations
- combinations_with_replacement
- permutations
- product
- Фильтрация последовательности
- filterfalse
- dropwhile
- takewhile
- compress
- Прочие итераторы
- chain
- chain.from_iterable
- starmap
- accumulate
- islice
- zip_longest
- tee
- groupby
- Резюме
- Заключение
Стандартная библиотека функций языка Python дает возможность программисту создавать определенные последовательности объектов и всячески ими манипулировать. При помощи простых итераций, действующих в цикле, можно наполнять массивы неким содержимым, а пользуясь генераторами списков – задавать более сложные условия для их формирования. Подключаемый модуль itertools позволяет расширить данный функционал.
Что такое itertools?
Данное расширение является сборником полезных итераторов, повышающих эффективность работы с циклами и генераторами последовательностей объектов. Это достигается за счет лучшего управления памятью в программе, быстрого выполнения подключаемых функций, а также сокращения и упрощения кода. Готовые методы, реализованные в данной библиотеке, принимают различные параметры для управления генератором последовательности, чтобы вернуть вызывающей подпрограмме необходимый набор объектов.
В этой статье рассматривается модуль itertools, присутствующий в 3-ей версии языка Python, хотя он также доступен и для Python 2. Чтобы воспользоваться возможностями данного пакета, стоит импортировать библиотеку, предварительно указав метод, к которому будет происходить обращение в программе. Например, для вызова функции product, следует поместить в начало файла следующую инструкцию: from itertools import product
. После этого программист получает возможность обращаться к методу по его имени. Если нужно использовать несколько функций — можно их названия перечислить через запятую.
Можно так же подключить модуль itertools в Python просто записав в начале программы import itertools *
. При таком подключении необходимо будет обращаться к той же функции product следующим образом: itertools.product( [аргументы функции] )
.
Бесконечная итерация
На сегодняшний день существует три функции-итератора, действие которых не прерывается автоматически.
К ним относятся методы:
- count;
- cycle;
- repeat.
С помощью этих методов можно генерировать объекты или совершать определенные действия неограниченное количество раз. Это значит, что программисту потребуется самостоятельно прервать созданный цикл.
count
Данный метод создает равномерно распределенную последовательность, генерируя объекты при помощи одного или двух параметров пользователя. Первым аргументом здесь является стартовое значение набора данных, а вторым (необязательным) – длина постоянного шага. Следующий пример демонстрирует работу этого метода в небольшом цикле.
from itertools import count for i in count(0, 2): if i >= 10: break else: print(i) 0 2 4 6 8
Как видно из результатов выполнения программы, цикл for работает с функцией count, которая в свою очередь получает стартовое значение последовательности 0 и длину шага 2. Переменная под названием i является временным хранилищем для каждого нового числа. В теле цикла используется конструкция if, ограничивающая действие генератора значением 10. Если в текущей итерации i меньше или равно 10, цикл прерывается при помощи break. В противном же случае происходит вывод значения через функцию print.
cycle
Следующий итератор позволяет создать бесконечный цикл, поочередно выводящий некие символы или числа. В качестве аргумента в данном случае выступает объект либо некий набор объектов, которые можно перечислить один за другим. Код, приведенный ниже, показывает работу функции cycle со строкой DOG в цикле for.
from itertools import cycle count = 1 for i in cycle('DOG'): if count > 5: break print(i) count += 1 D O G D O
Таким образом, результатом работы программы становится поочередный вывод символов строки, которая является аргументом метода cycle. Поскольку данный итератор также не имеет автоматических ограничений на число новых объектов, стоит воспользоваться счетчиком для его остановки. С помощью переменной count, увеличивающей свое значение на 1 за каждый шаг цикла, эта задача решается довольно просто.
repeat
Последний из подобных итераторов осуществляет повторение объекта, который был передан в качестве первого параметра в метод. Вторым аргументом является количество идентичных элементов в создаваемой последовательности. Следующий пример показывает заполнение списка с именем data при помощи генератора с циклом for. В роли объекта здесь выступает строка DOG, которую добавляют в последовательность ровно 3 раза.
from itertools import repeat data = [i for i in repeat('DOG', 3)] print(data) ['DOG', 'DOG', 'DOG']
Результаты работы программы отображаются благодаря методу print, получающему готовый список data для вывода на экран. На месте первого параметра функции repeat может стоять не только строка, но и число, символ, а также другой список с любыми данными.
Комбинация значений
В данный момент имеется всего четыре функции-итератора, позволяющие комбинировать различные значения, меняя местами их составляющие. К их числу относятся такие методы как:
- combinations;
- combinations_with_replacement;
- permutations;
- product.
combinations
Первая функция по комбинированию отдельных элементов последовательности принимает два аргумента, как и все последующие. Первый позволяет задать определенный объект, а второй – количество значений, которые будут присутствовать в каждом новом отрезке. В данном примере демонстрируется работа в Python функции combinations библиотеки itertools при создании списка.
from itertools import combinations data = list(combinations('DOG', 2)) print(data) [('D', 'O'), ('D', 'G'), ('O', 'G')]
Как видно из кода, метод получает строку DOG, которая впоследствии раскладывается на отдельные символы. Далее происходит группировка по 2 буквы так, чтобы каждая новая выборка отличалась от всех существующих. Функция print выводит полученный список data на экран, отображая все сформированные пары символов D, O, G.
combinations_with_replacement
Более продвинутая вариация предыдущего итератора предоставляет программе возможность делать выборку из отдельных элементов с учетом их порядка. В следующем образце кода показано использование combinations_with_replacement с уже известными аргументами.
from itertools import combinations_with_replacement for i in combinations_with_replacement('DOG', 2): print(''.join(i)) DD DO DG OO OG GG
В результате работы программы, на экране отобразилось несколько групп элементов, не повторяющих порядок друг друга. При этом вполне могут использоваться одинаковые объекты, если их общее расположение не совпадает с предыдущими выборками.
permutations
Работа функции permutations модуля itertools в Python похожа на комбинацию со сменой порядка. Однако в ней не допускается размещение идентичных элементов в одной группе. Ниже приведен код, демонстрирующий поведение и результат выполнения этого метода в цикле for.
from itertools import permutations for i in permutations('DOG', 2): print(''.join(i)) DO DG OD OG GD GO
На выходе программа отображает несколько пар значений, так как в качестве второго аргумента функция получила 2. Важно заметить, что каждая новая выборка отличается от всех предыдущих только порядком, а общая последовательность может включать в себя группы, состоящие из одних и тех же значений, просто сменивших расположение.
product
Последний из комбинационных итераторов получает в качестве параметра массив данных, состоящий из нескольких групп значений. Функция product библиотеки itertools в Python 3 позволяет получить из введенной последовательности чисел или символов новую совокупность групп во всех возможных вариациях. Следующий пример показывает исполнение этого метода.
from itertools import product data = list(product((0, 1), (2, 3))) print(data) [(0, 2), (0, 3), (1, 2), (1, 3)]
Таким образом, получается новая последовательность data, вмещающая в себя все возможные комбинации значений, полученных из начального списка. Как и в других примерах, функция print выводит все ее содержимое на экран.
Фильтрация последовательности
Для управления данными в списке или любой другой последовательности значений также используются инструменты фильтрации. Некоторые функции, входящие в состав пакета itertools умеют автоматически удалять отдельные элементы, не удовлетворяющие заданных программистом условий. На данный момент времени таких итераторов существует всего четыре:
- filterfalse;
- dropwhile;
- takewhile;
- compress.
filterfalse
Для создания нового списка из уже имеющейся последовательности объектов можно применять метод фильтрации filterfalse. В качестве первого аргумента здесь выступает проверочная функция, возвращающая булево значение True или False. Вторым параметром является список неких объектов, над которыми нужно провести фильтрацию, воспользовавшись результатом выполнения проверочной функции.
from itertools import filterfalse data = list(filterfalse(lambda i: i == 0, [1, 2, 3, 0, 4, 5, 1])) print(data) [1, 2, 3, 4, 5, 1]
Как можно увидеть из примера, в лямбда-функции осуществляется проверка на равность нулю. Элементы последовательности, для которых такая проверка возвращает False, заносятся в новый список, после чего выдаются на экран.
dropwhile
Следующая функция работает несколько иным образом, хотя используется та же схема. Итератор dropwhile проверяет булево значение, возвращаемое в качестве первого параметра для каждого элемента последовательности, и в том случае, если он равен False, записывает его в новый список, а также все, что идет после.
from itertools import dropwhile data = list(dropwhile(lambda i: i != 0, [1, 2, 3, 0, 4, 5, 1])) print(data) [0, 4, 5, 1]
В данном примере показано, что при помощи лямбда-функции выполняется проверка на неравенство нулю. После того как в последовательности найден 0, все последующие числовые значения сохраняются в новый список.
takewhile
Совершенно противоположным образом работает итератор takewhile, записывая в массив только те элементы, которые шли до возврата проверочной функцией значения False. Следующий пример демонстрирует работу данного метода.
from itertools import takewhile data = list(takewhile(lambda i: i != 0, [1, 2, 3, 0, 4, 5, 1])) print(data) [1, 2, 3]
Как можно заметить, результирующий список получил значения, которые шли до 0.
compress
Иногда возникает необходимость в удалении ненужных объектов последовательности, просто передав ей булевы значения. Для этого используется метод compress, получающий в следующем примере строку и набор из True и False для каждого ее символа.
from itertools import compress data = list(compress('DOG', [True, False, True])) print(data) ['D', 'G']
В результате получается список, в котором присутствуют только элементы, отмеченные ранее как True. Символ O был удален, так как ему соответствовал False.
Прочие итераторы
Несмотря на то, что существуют инструменты библиотеки itertools, не вошедшие ни в один из описанных ранее разделов, их применение иногда также бывает очень полезным для решения многих довольно специфических задач. Часто они становятся актуальны в паре с другими итераторами. Далее будут описаны такие методы как:
- chain;
- chain.from_iterable
- starmap
- accumulate;
- islice;
- izip;
- tee;
- groupby.
chain
Функция chain выполняет объединение списков, как это показано в следующем примере для data1 и data2. Итоговый массив содержит все элементы данных последовательностей.
from itertools import chain data1 = ['D', 'O', 'G'] data2 = [0, 1, 2, 3, 4] data = list(chain(data1, data2)) print(data) ['D', 'O', 'G', 0, 1, 2, 3, 4]
chain.from_iterable
Работает аналогично chain. Также выполняется объединение списков. Отличие заключается в том, что аргумент только один — вложенный список со списками, которые надо объединить.
from itertools import chain data = [['D', 'O', 'G'], [0, 1, 2, 3, 4]] data2 = [0, 1, 2, 3, 4] data = list(chain.from_iterable(data)) print(data) ['D', 'O', 'G', 0, 1, 2, 3, 4]
starmap
Первый аргумент — это функция. Второй аргумент — это с писок параметров, подаваемых на функцию. В качестве примера была взята стандартная функция pow, которая позволяет возводить число в степень.
from itertools import starmap for i in starmap(pow, [(1, 2), (2, 2), (3, 2)]): print(i) 1 4 9
accumulate
Данная функция модуля itertools — accumulate высчитывает сумму предыдущих элементов и добавляет текущий к ней. Вот пример:
from itertools import accumulate data = list(accumulate([1,2,3,4])) print(data) [1, 3, 6, 10]
Видно из кода, что первый полученный элемент равен первому заданному значению. Второй — это сумма предыдущего результата со вторым заданным значением. И так далее.
islice
Итератор islice позволяет ограничить заполнение списка новыми элементами, если ввести в качестве параметра желаемое количество объектов. Данный пример показывает совместную работу методов count и islice для создания 5 чисел, начиная с 0 и с шагом 2.
from itertools import islice from itertools import count for i in islice(count(0, 2), 5): print(i) 0 2 4 6 8
zip_longest
Функция zip_longest требуется в тех случаях, когда необходимо произвести спаривание отдельных элементов последовательности. Параметр fillvalue позволяет обозначить объект, которым будут заполнятся недостающие ячейки списка.
from itertools import zip_longest for i in zip_longest('DOG', [0, 1, 2, 3], fillvalue = ' '): print (i) ('D', 0) ('O', 1) ('G', 2) (' ', 3)
tee
Метод tee используется для генерации собственных итераторов на основе итерируемой последовательности объектов. В примере показано создание итераторов i1 и i2.
from itertools import tee data = 'DOG' i1, i2 = tee(data) for i in i1: print(i) for i in i2: print(i) D O G D O G
groupby
Последняя функция в этом разделе называется groupby и применяется для группировки объектов списка по общим значениям. Приведенный код показывает форматированную выдачу данных массива animals. Как видно из примера, метод itertools groupby принимает в качестве первого аргумента сам список, в то время как на месте второго стоит лямбда-функция.
from itertools import groupby animals = [('CAT', 'TOM'), ('MOUSE', 'JARRY')] for key, group in groupby(animals, lambda kind: kind[0]): for kind, name in group: print('{name} is a {kind}'.format(name = name, kind = kind)) TOM is a CAT JARRY is a MOUSE
Резюме
Таким образом, в данной статье были описаны все методы, включенные в состав пакета itertools. Следующая таблица отображает краткую сводку по всем пройденным функциям, включая в себя особенности их вызова и назначение.
Название | Назначение |
count | Итерация с заданным шагом без ограничений |
cycle | Итерация с повторением без ограничений |
repeat | Итерация с повторением заданное количество раз |
combinations | Комбинация всех возможных значений без повторяющихся элементов |
combinations_with_replacement | Комбинация всех возможных значений с повторяющимися элементами |
permutations | Комбинация с перестановкой всех возможных значений |
product | Комбинация, полученная из всех возможных значений вложенных списков |
filterfalse | Все элементы, для которых функция возвращает ложь |
dropwhile | Все элементы, начиная с того, для которого функция вернет ложь |
takewhile | Все элементы, до тех пор, пока функция не вернет истину |
compress | Удаление элементов, для которых было передано значение ложь |
chain | Поочередное объединение списков при помощи итераторов |
chain.from_terable | Аналогично chain, но аргумент — список, в который вложены объединяемые списки. |
islice | Получение среза, благодаря указанному количеству элементов |
zip_longest | Объединение нескольких итераций с повышением размера до максимального |
tee | Создание кортежа из нескольких готовых итераторов |
groupby | Группировка элементов последовательности по некоторым ключевым значениям |
accumulate | Каждый элемент результирующей последовательности равен сумме текущего и всех предыдущих исходной последовательности |
starmap | В заданную функцию передает список подставляемых аргументов |
Заключение
Библиотека itertools содержит массу полезных методов. Они помогают генерировать списки, а также любые другие последовательности значений с определенными условиями. Пользуясь ее возможностями, можно заполнять наборы данных числами с итерацией, комбинировать символы строк и фильтровать элементы массива по признакам. В данной статье описаны все методы библиотеки itertools, содержащиеся в официальной документации Python 3. Для большей наглядности приведены подробные примеры использования функций.