product python что это
Модуль itertools
Python предоставляет замечательный модуль для создания собственных итераторов. Я говорю о модуле itertools. Предоставленные данным модулем инструменты быстрые и эффективно используют память. Вы сможете использовать эти кирпичики для создания собственных специализированных итераторов, которые могут использоваться для эффективных циклов. В данной статье мы рассмотрим примеры каждого предоставленного инструмента, так что к её концу вы сможете эффективно использовать каждый инструмент для создания собственных скриптов, а главное, знать, когда именно их применять.
Бесконечные итераторы
Пакет itertools содержит три итератора, которые могут выполнять итерацию бесконечно. Это означает, что когда вы используете их, вам нужно прекрасно понимать, что в конечном итоге вам нужно разорвать эти итераторы, во избежание бесконечного цикла. Это может быть применимо при генерации чисел или при циклическом переключении по итерациям неизвестной длины, например. Давайте начнем с изучения этих итераций!
count(start=0, step=1)
Итератор count возвращает равномерно распределенные переменные, начиная с числа, которое вы передаете в качестве стартового параметра. Он также принимает параметр шага. Давайте взглянем на простой пример:
Итерируем правильно: 20 приемов использования в Python модуля itertools
Leo Matyushkin
В декабре 2019 года мы подробно рассказали о модуле collections. Другой важный компонент стандартной библиотеки – itertools.
Модуль itertools содержит строительные блоки итераторов, основанные на конструкциях из языков программирования APL, Haskell и SML. Ниже мы опишем набор быстрых и эффективных в отношении памяти инструментов, полезных как самостоятельно, так и в сочетании. Вместе они образуют «алгебру итераторов» для программ на чистом Python.
Цель публикации – в сжатой форме рассмотреть распространённые примеры и шаблоны использования модуля itertools.
Если вы владеете Jupyter Notebook, блокнот этой статьи доступен на GitHub. Соответственно код легко запустить в интерактивном режиме с помощью Colab.
1. Бесконечный счётчик
Функция itertools.count(start=0, step=1) создаёт бесконечный итератор. Можно задать начальное значение и шаг итерирования.
Если необходимо подсчитывать число вхождений элементов в список или кортеж, обратите внимание на Counter() из модуля collections.
2. Упаковка по более длинной последовательности
Если последовательности имеют неодинаковую длину, zip() ограничивается самой короткой:
Но такое сокращение может быть неудобно из-за потери информации. Чтобы сохранить обе последовательности, используйте itertools.zip_longest() :
3. Аккумулирующий итератор
Суммирование нарастающим (накопительным) итогом – вид сложения последовательности чисел. Например, так считается квартальная прибыль Каждый элемент складывается с суммой всех предшествовавших элементов. В следующем примере 1 и 2 даёт 3, сумма 1, 2 и 3 равна 6 и т. д. Описанный тип работы с последовательностью воплощен в itertools.accumulate(iterable, func=operator.add, *, initial=None) :
Чтобы вывести данные, мы используем список. При печати самого итератора выводится только его ссылка.
4. Бесконечный итератор последовательности
С помощью itertools.cycle() создаётся кольцевой итератор. Прийдя к последнему значению, он вновь начинает с первого:
5. Бесконечный итератор одного объекта
Классический пример использования itertools.repeat() – итератор для map() :
6. Мапирование с распаковкой
7. Комбинаторика: сочетания
Модуль itertools позволяет решать программные задачи, построенные на структурах комбинаторики.
Сочетания – выбранные из множества n объектов комбинации m объектов, отличающиеся хотя бы одним объектом. Порядок элементов не важен.
Например, мы хотим составить трёхцветный флаг из лент цветных тканей. Есть четыре цвета лент. Все варианты выбора тканей без учёта их расположения:
Порядок следования не имеет значения, поэтому все тройки цветов уникальны.
8. Комбинаторика: размещения
Размещения – те же сочетания, для которых важен порядок следования элементов. В продолжение предыдущего примера определим все варианты как мы можем составить флаг с учётом порядка следования цветов:
Как и ожидалось, число комбинаций с учетом порядка элементов гораздо больше.
9. Комбинаторика: размещение с повторениями
Размещение с повторениями (выборка с возвращением) – это комбинаторное размещение объектов, в котором каждый объект может участвовать в размещении несколько раз.
10. Комбинаторика: размещение
Рассмотрим также случай обычного размещения, когда элементы могут повторяться, но каждое сочетание встречается только один раз:
11. Декартово произведение множеств
Метод itertools.product() можно использовать не только для размещений с повторениями.
Декартово (прямое) произведение – множество, элементами которого являются все возможные упорядоченные пары элементов исходных множеств.
Например, найдём обозначения всех полей шахматной доски:
12. Цепочки итераторов
Например, мы хотим использовать для отрисовки игральных карт независимые итераторы обозначений в углу поля карты:
С помощью itertools.chain() также можно добавлять отдельные элементы в начало итератора:
13. Плоский список из вложенного
Последний конструктор удобно использовать для объединения списков:
14. Итератор среза
Например, нам достаточно читать из крупного файла только три первых строки:
Функция itertools.islice() позволяет итерироваться по любым объектам в формате среза. Например, следующая функция возвращает n первых элементов итерируемого объекта в виде списка:
15. Фильтрация группы элементов
Функция compress() оставляет из итерируемых данных только те, что соответствуют позициям булевых селекторов:
Метод itertools.filterfalse() дополняет обычный фильтр filter() :
16. Фильтрация до последнего истинного (или с первого ложного) элемента
Если необходимо отобрать объекты, стоящие после неудовлетворяющего условию элемента, используем itertools.dropwhile() :
Метод itertools.takewhile() наоборот выведет элементы, удовлетворяющие условию вплоть до объекта, прерывающего цепочку истинных элементов:
17. Группировка по ключу
Инструмент itertools.groupby() объединяет смежные словари в группы по общему ключу. Например, сгруппируем студентов с одинаковой оценкой:
Обратите внимание, что группировка работает только со смежными объектами. Предварительно отсортируйте данные.
18. Репликация итераторов
Функция itertools.tee() создаёт из одного итерируемого объекта два итератора:
Эти итераторы соответствуют одной последовательности, но независимы друг от друга.
19. Повторение последовательности заданное число раз
Волшебная сила itertools – в умении комбинировать итераторы, чтобы писать быстрый, эффективный и ясный код.
Например, сочетание itertools.chain() и itertools.from_iterable() даёт ограниченный вариант бесконечного itertools.cycle() :
20. Уникальные элементы последовательности
Напоследок напишем функцию, выводящую все уникальные элементы в том же порядке, как они появлялись в исходной последовательности. Опциональный аргумент – ссылка на функцию определения эквивалентов, представленных по-разному. Например, заглавных и строчных букв.
Заключение
Описывая приёмы использования itertools, мы попутно определили основные функции модуля.
Итераторы полезны для обработки крупных файлов и потоков данных, для доступа к содержимому объектов без раскрытия их полного внутреннего представления.
Модуль itertools обеспечивает ключевые структуры итераторов Python. Другие шаблоны вы найдёте в специальной библиотеке примеров more-itertools :
itertools — Functions creating iterators for efficient looping¶
This module implements a number of iterator building blocks inspired by constructs from APL, Haskell, and SML. Each has been recast in a form suitable for Python.
The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python.
Infinite iterators:
start, start+step, start+2*step, …
p0, p1, … plast, p0, p1, …
elem, elem, elem, … endlessly or up to n times
Iterators terminating on the shortest input sequence:
p0, p1, … plast, q0, q1, …
p0, p1, … plast, q0, q1, …
(d[0] if s[0]), (d[1] if s[1]), …
seq[n], seq[n+1], starting when pred fails
elements of seq where pred(elem) is false
sub-iterators grouped by value of key(v)
seq, [start,] stop [, step]
elements from seq[start:stop:step]
func(*seq[0]), func(*seq[1]), …
seq[0], seq[1], until pred fails
it1, it2, … itn splits one iterator into n
Combinatoric iterators:
cartesian product, equivalent to a nested for-loop
r-length tuples, all possible orderings, no repeated elements
r-length tuples, in sorted order, no repeated elements
r-length tuples, in sorted order, with repeated elements
AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
AB AC AD BA BC BD CA CB CD DA DB DC
AA AB AC AD BB BC BD CC CD DD
Itertool functionsВ¶
The following module functions all construct and return iterators. Some provide streams of infinite length, so they should only be accessed by functions or loops that truncate the stream.
Make an iterator that returns accumulated sums, or accumulated results of other binary functions (specified via the optional func argument).
Usually, the number of elements output matches the input iterable. However, if the keyword argument initial is provided, the accumulation leads off with the initial value so that the output has one more element than the input iterable.
Roughly equivalent to:
There are a number of uses for the func argument. It can be set to min() for a running minimum, max() for a running maximum, or operator.mul() for a running product. Amortization tables can be built by accumulating interest and applying payments. First-order recurrence relations can be modeled by supplying the initial value in the iterable and using only the accumulated total in func argument:
See functools.reduce() for a similar function that returns only the final accumulated value.
Changed in version 3.3: Added the optional func parameter.
Changed in version 3.8: Added the optional initial parameter.
Make an iterator that returns elements from the first iterable until it is exhausted, then proceeds to the next iterable, until all of the iterables are exhausted. Used for treating consecutive sequences as a single sequence. Roughly equivalent to:
Return r length subsequences of elements from the input iterable.
The combination tuples are emitted in lexicographic ordering according to the order of the input iterable. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.
Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each combination.
Roughly equivalent to:
The code for combinations() can be also expressed as a subsequence of permutations() after filtering entries where the elements are not in sorted order (according to their position in the input pool):
Return r length subsequences of elements from the input iterable allowing individual elements to be repeated more than once.
The combination tuples are emitted in lexicographic ordering according to the order of the input iterable. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.
Elements are treated as unique based on their position, not on their value. So if the input elements are unique, the generated combinations will also be unique.
Roughly equivalent to:
The code for combinations_with_replacement() can be also expressed as a subsequence of product() after filtering entries where the elements are not in sorted order (according to their position in the input pool):
Make an iterator that returns evenly spaced values starting with number start. Often used as an argument to map() to generate consecutive data points. Also, used with zip() to add sequence numbers. Roughly equivalent to:
Changed in version 3.1: Added step argument and allowed non-integer arguments.
Make an iterator returning elements from the iterable and saving a copy of each. When the iterable is exhausted, return elements from the saved copy. Repeats indefinitely. Roughly equivalent to:
Note, this member of the toolkit may require significant auxiliary storage (depending on the length of the iterable).
Make an iterator that drops elements from the iterable as long as the predicate is true; afterwards, returns every element. Note, the iterator does not produce any output until the predicate first becomes false, so it may have a lengthy start-up time. Roughly equivalent to:
The operation of groupby() is similar to the uniq filter in Unix. It generates a break or new group every time the value of the key function changes (which is why it is usually necessary to have sorted the data using the same key function). That behavior differs from SQL’s GROUP BY which aggregates common elements regardless of their input order.
groupby() is roughly equivalent to:
itertools. pairwise ( iterable ) В¶
Return successive overlapping pairs taken from the input iterable.
The number of 2-tuples in the output iterator will be one fewer than the number of inputs. It will be empty if the input iterable has fewer than two values.
Roughly equivalent to:
New in version 3.10.
Return successive r length permutations of elements in the iterable.
The permutation tuples are emitted in lexicographic ordering according to the order of the input iterable. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.
Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each permutation.
Roughly equivalent to:
Cartesian product of input iterables.
The nested loops cycle like an odometer with the rightmost element advancing on every iteration. This pattern creates a lexicographic ordering so that if the input’s iterables are sorted, the product tuples are emitted in sorted order.
This function is roughly equivalent to the following code, except that the actual implementation does not build up intermediate results in memory:
Before product() runs, it completely consumes the input iterables, keeping pools of values in memory to generate the products. Accordingly, it is only useful with finite inputs.
Make an iterator that returns object over and over again. Runs indefinitely unless the times argument is specified. Used as argument to map() for invariant parameters to the called function. Also used with zip() to create an invariant part of a tuple record.
Roughly equivalent to:
A common use for repeat is to supply a stream of constant values to map or zip:
Make an iterator that returns elements from the iterable as long as the predicate is true. Roughly equivalent to:
Return n independent iterators from a single iterable.
The following Python code helps explain what tee does (although the actual implementation is more complex and uses only a single underlying FIFO queue).
Roughly equivalent to:
Once tee() has made a split, the original iterable should not be used anywhere else; otherwise, the iterable could get advanced without the tee objects being informed.
tee iterators are not threadsafe. A RuntimeError may be raised when using simultaneously iterators returned by the same tee() call, even if the original iterable is threadsafe.
Make an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted. Roughly equivalent to:
Itertools RecipesВ¶
This section shows recipes for creating an extended toolset using the existing itertools as building blocks.
Substantially all of these recipes and many, many others can be installed from the more-itertools project found on the Python Package Index:
The extended tools offer the same high performance as the underlying toolset. The superior memory performance is kept by processing elements one at a time rather than bringing the whole iterable into memory all at once. Code volume is kept small by linking the tools together in a functional style which helps eliminate temporary variables. High speed is retained by preferring “vectorized” building blocks over the use of for-loops and generator s which incur interpreter overhead.
Itertools
Стандартная библиотека функций языка Python дает возможность программисту создавать определенные последовательности объектов и всячески ими манипулировать. При помощи простых итераций, действующих в цикле, можно наполнять массивы неким содержимым, а пользуясь генераторами списков – задавать более сложные условия для их формирования. Подключаемый модуль itertools позволяет расширить данный функционал.
Что такое itertools?
Данное расширение является сборником полезных итераторов, повышающих эффективность работы с циклами и генераторами последовательностей объектов. Это достигается за счет лучшего управления памятью в программе, быстрого выполнения подключаемых функций, а также сокращения и упрощения кода. Готовые методы, реализованные в данной библиотеке, принимают различные параметры для управления генератором последовательности, чтобы вернуть вызывающей подпрограмме необходимый набор объектов.
Бесконечная итерация
На сегодняшний день существует три функции-итератора, действие которых не прерывается автоматически.
К ним относятся методы:
С помощью этих методов можно генерировать объекты или совершать определенные действия неограниченное количество раз. Это значит, что программисту потребуется самостоятельно прервать созданный цикл.
count
Данный метод создает равномерно распределенную последовательность, генерируя объекты при помощи одного или двух параметров пользователя. Первым аргументом здесь является стартовое значение набора данных, а вторым (необязательным) – длина постоянного шага. Следующий пример демонстрирует работу этого метода в небольшом цикле.
Как видно из результатов выполнения программы, цикл for работает с функцией count, которая в свою очередь получает стартовое значение последовательности 0 и длину шага 2. Переменная под названием i является временным хранилищем для каждого нового числа. В теле цикла используется конструкция if, ограничивающая действие генератора значением 10. Если в текущей итерации i меньше или равно 10, цикл прерывается при помощи break. В противном же случае происходит вывод значения через функцию print.
cycle
Следующий итератор позволяет создать бесконечный цикл, поочередно выводящий некие символы или числа. В качестве аргумента в данном случае выступает объект либо некий набор объектов, которые можно перечислить один за другим. Код, приведенный ниже, показывает работу функции cycle со строкой DOG в цикле for.
Таким образом, результатом работы программы становится поочередный вывод символов строки, которая является аргументом метода cycle. Поскольку данный итератор также не имеет автоматических ограничений на число новых объектов, стоит воспользоваться счетчиком для его остановки. С помощью переменной count, увеличивающей свое значение на 1 за каждый шаг цикла, эта задача решается довольно просто.
repeat
Последний из подобных итераторов осуществляет повторение объекта, который был передан в качестве первого параметра в метод. Вторым аргументом является количество идентичных элементов в создаваемой последовательности. Следующий пример показывает заполнение списка с именем data при помощи генератора с циклом for. В роли объекта здесь выступает строка DOG, которую добавляют в последовательность ровно 3 раза.
Результаты работы программы отображаются благодаря методу print, получающему готовый список data для вывода на экран. На месте первого параметра функции repeat может стоять не только строка, но и число, символ, а также другой список с любыми данными.
Комбинация значений
В данный момент имеется всего четыре функции-итератора, позволяющие комбинировать различные значения, меняя местами их составляющие. К их числу относятся такие методы как:
combinations
Первая функция по комбинированию отдельных элементов последовательности принимает два аргумента, как и все последующие. Первый позволяет задать определенный объект, а второй – количество значений, которые будут присутствовать в каждом новом отрезке. В данном примере демонстрируется работа в Python функции combinations библиотеки itertools при создании списка.
Как видно из кода, метод получает строку DOG, которая впоследствии раскладывается на отдельные символы. Далее происходит группировка по 2 буквы так, чтобы каждая новая выборка отличалась от всех существующих. Функция print выводит полученный список data на экран, отображая все сформированные пары символов D, O, G.
combinations_with_replacement
Более продвинутая вариация предыдущего итератора предоставляет программе возможность делать выборку из отдельных элементов с учетом их порядка. В следующем образце кода показано использование combinations_with_replacement с уже известными аргументами.
В результате работы программы, на экране отобразилось несколько групп элементов, не повторяющих порядок друг друга. При этом вполне могут использоваться одинаковые объекты, если их общее расположение не совпадает с предыдущими выборками.
permutations
Работа функции permutations модуля itertools в Python похожа на комбинацию со сменой порядка. Однако в ней не допускается размещение идентичных элементов в одной группе. Ниже приведен код, демонстрирующий поведение и результат выполнения этого метода в цикле for.
На выходе программа отображает несколько пар значений, так как в качестве второго аргумента функция получила 2. Важно заметить, что каждая новая выборка отличается от всех предыдущих только порядком, а общая последовательность может включать в себя группы, состоящие из одних и тех же значений, просто сменивших расположение.
product
Последний из комбинационных итераторов получает в качестве параметра массив данных, состоящий из нескольких групп значений. Функция product библиотеки itertools в Python 3 позволяет получить из введенной последовательности чисел или символов новую совокупность групп во всех возможных вариациях. Следующий пример показывает исполнение этого метода.
Таким образом, получается новая последовательность data, вмещающая в себя все возможные комбинации значений, полученных из начального списка. Как и в других примерах, функция print выводит все ее содержимое на экран.
Фильтрация последовательности
Для управления данными в списке или любой другой последовательности значений также используются инструменты фильтрации. Некоторые функции, входящие в состав пакета itertools умеют автоматически удалять отдельные элементы, не удовлетворяющие заданных программистом условий. На данный момент времени таких итераторов существует всего четыре:
filterfalse
Для создания нового списка из уже имеющейся последовательности объектов можно применять метод фильтрации filterfalse. В качестве первого аргумента здесь выступает проверочная функция, возвращающая булево значение True или False. Вторым параметром является список неких объектов, над которыми нужно провести фильтрацию, воспользовавшись результатом выполнения проверочной функции.
Как можно увидеть из примера, в лямбда-функции осуществляется проверка на равность нулю. Элементы последовательности, для которых такая проверка возвращает False, заносятся в новый список, после чего выдаются на экран.
dropwhile
Следующая функция работает несколько иным образом, хотя используется та же схема. Итератор dropwhile проверяет булево значение, возвращаемое в качестве первого параметра для каждого элемента последовательности, и в том случае, если он равен False, записывает его в новый список, а также все, что идет после.
В данном примере показано, что при помощи лямбда-функции выполняется проверка на неравенство нулю. После того как в последовательности найден 0, все последующие числовые значения сохраняются в новый список.
takewhile
Совершенно противоположным образом работает итератор takewhile, записывая в массив только те элементы, которые шли до возврата проверочной функцией значения False. Следующий пример демонстрирует работу данного метода.
Как можно заметить, результирующий список получил значения, которые шли до 0.
compress
Иногда возникает необходимость в удалении ненужных объектов последовательности, просто передав ей булевы значения. Для этого используется метод compress, получающий в следующем примере строку и набор из True и False для каждого ее символа.
В результате получается список, в котором присутствуют только элементы, отмеченные ранее как True. Символ O был удален, так как ему соответствовал False.
Прочие итераторы
Несмотря на то, что существуют инструменты библиотеки itertools, не вошедшие ни в один из описанных ранее разделов, их применение иногда также бывает очень полезным для решения многих довольно специфических задач. Часто они становятся актуальны в паре с другими итераторами. Далее будут описаны такие методы как:
chain
Функция chain выполняет объединение списков, как это показано в следующем примере для data1 и data2. Итоговый массив содержит все элементы данных последовательностей.
chain.from_iterable
Работает аналогично chain. Также выполняется объединение списков. Отличие заключается в том, что аргумент только один — вложенный список со списками, которые надо объединить.
starmap
Первый аргумент — это функция. Второй аргумент — это с писок параметров, подаваемых на функцию. В качестве примера была взята стандартная функция pow, которая позволяет возводить число в степень.
accumulate
Данная функция модуля itertools — accumulate высчитывает сумму предыдущих элементов и добавляет текущий к ней. Вот пример:
Видно из кода, что первый полученный элемент равен первому заданному значению. Второй — это сумма предыдущего результата со вторым заданным значением. И так далее.
islice
Итератор islice позволяет ограничить заполнение списка новыми элементами, если ввести в качестве параметра желаемое количество объектов. Данный пример показывает совместную работу методов count и islice для создания 5 чисел, начиная с 0 и с шагом 2.
zip_longest
Функция zip_longest требуется в тех случаях, когда необходимо произвести спаривание отдельных элементов последовательности. Параметр fillvalue позволяет обозначить объект, которым будут заполнятся недостающие ячейки списка.
Метод tee используется для генерации собственных итераторов на основе итерируемой последовательности объектов. В примере показано создание итераторов i1 и i2.
groupby
Последняя функция в этом разделе называется groupby и применяется для группировки объектов списка по общим значениям. Приведенный код показывает форматированную выдачу данных массива animals. Как видно из примера, метод itertools groupby принимает в качестве первого аргумента сам список, в то время как на месте второго стоит лямбда-функция.
Резюме
Таким образом, в данной статье были описаны все методы, включенные в состав пакета 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. Для большей наглядности приведены подробные примеры использования функций.