Рубрики
Без рубрики

Руководство по использованию модуля Python Itertools

В этой статье мы рассмотрим использование модуля Python itertools.

Автор оригинала: Pankaj Kumar.

В этой статье мы рассмотрим использование модуля Python itertools.

Этот модуль очень полезен, если вы хотите создать различные типы итераторов, подходящих для различных задач.

Если вы сможете изучить некоторые методы этого модуля, это может быть очень полезным дополнением к вашему набору инструментов! Давайте начнем прямо сейчас, перейдя к некоторым полезным методам.

Python Itertools – Полезные методы

В этом разделе мы рассмотрим некоторые полезные методы, которые генерируют итераторы.

Чтобы использовать этот модуль, мы должны сначала импортировать его. Это уже доступно в стандартной библиотеке, поэтому оно предварительно установлено!

import itertools

Использование Python itertools.chain() для объединения итераций в цепочку

Метод Python itertools.chain() генерирует итератор из нескольких итераций.

Это просто объединяет все итеративные объекты в одну последовательность и возвращает один итератор в эту объединенную последовательность.

Синтаксис этого метода выглядит следующим образом

iterator = itertools.chain(*sequence)

Давайте рассмотрим простой пример, чтобы понять это.

import itertools

list1 = ['hello', 'from', 'AskPython']
list2 = [10, 20, 30, 40, 50]
dict1 = {'site': 'AskPython', 'url': 'https://askpython.com'}

# We can combine lists and dicts (iterables) into a single chain
for item in itertools.chain(list1, list2, dict1):
    print(item)

Здесь мы используем итератор напрямую, повторяя его, используя для элемента in ...

Выход

hello
from
AskPython
10
20
30
40
50
site
url

Здесь, хотя мы правильно получаем содержимое наших списков, значения словаря не отображаются.

Чтобы исправить это, мы могли бы использовать dict.items() для получения кортежа пар (ключ, значение) .

import itertools

list1 = ['hello', 'from', 'AskPython']
list2 = [10, 20, 30, 40, 50]
dict1 = {'site': 'AskPython', 'url': 'https://askpython.com'}

# We can combine lists and dicts (iterables) into a single chain
for item in itertools.chain(list1, list2, dict1.items()):
    print(item)

Выход

hello
from
AskPython
10
20
30
40
50
('site', 'AskPython')
('url', 'https://askpython.com')

Действительно, теперь у нас также есть значения, напечатанные с помощью dict1.items() в качестве итеративного!

Использование Python itertools.count() для создания последовательности на основе счетчика

Мы можем использовать функцию Python itertools.count() для создания итераторов, соответствующих счетчику.

iterator = itertools.count(start=0, step=1)

Здесь это итератор, который продолжает считать бесконечно, начиная с 0 и далее.

Это продолжает увеличивать количество на шаг=1 . Мы также можем установить это в десятичное/отрицательное число.

Например, если вы хотите доказать, что у вас есть бесконечный цикл, вы можете запустить приведенный ниже фрагмент, но это НЕ рекомендуется.

Просто убедитесь, что вы можете понять, что itertools.count() считает бесконечно.

for num in itertools.count(start=0, step=1):
    # Infinite loop!
    print(num)

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

Рассмотрим приведенный ниже пример:

import itertools
numbers = [100, 200, 300, 400]

data = list(zip(itertools.count(0, 10), numbers))

print(data)

Здесь вы теперь можете увидеть силу итераторов! Поскольку итераторы производят выходные данные только по требованию, мы можем zip() it с другой конечной итерацией, такой как список!

Теперь это используется для построения индексов для элементов в списке, как вы можете убедиться, используя выходные данные!

[(0, 100), (10, 200), (20, 300), (30, 400)]

Теперь, если вы хотите иметь подмножество последовательности итераторов с помощью Python itertools.count() , вы также можете использовать itertools.islice() для построения только фрагмента итератора.

import itertools

for num in itertools.islice(itertools.count(start=0, step=10), 4):
    print(num)

for num in itertools.islice(itertools.count(), 0, 50, 10):
    print(num)

Выход

0
10
20
30
0
10
20
30
40

Как вы можете заметить, обе последовательности идентичны. Это показывает, что у вас может быть несколько подходов для генерации последовательностей!

Используйте метод, который вы считаете нужным, основываясь на проблеме, которую нужно решить!

Использование itertools.repeat() для повторения значения

Предположим, вы хотите повторить определенное значение, вы можете построить итератор для повторяющегося значения с помощью itertools.repeat(value) .

Например, если вы хотите построить последовательность вида (i, 5) , где i колеблется от 0 до 10, вы можете использовать эту функцию!

import itertools

data = list(zip(range(10), itertools.repeat(5)))
print(data)

Выход

[(0, 5),
 (1, 5),
 (2, 5),
 (3, 5),
 (4, 5),
 (5, 5),
 (6, 5),
 (7, 5),
 (8, 5),
 (9, 5)]

Действительно, мы смогли легко сделать эту последовательность!

Другой пример, в котором эта функция полезна, – это если вы пытаетесь построить квадраты с помощью map() в Python .

squares = list(map(pow, range(10), itertools.repeat(2)))
print(squares)

Выход

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Видите, как легко мы смогли построить его с помощью map() ?

Использование itertools.tee() для клонирования последовательностей

Существует еще одна полезная функция, называемая tee() , которая клонирует последовательность и создает две последовательности.

cloned1, cloned2 = itertools.tee(original_sequence)

Это основано на команде Linux tee, которая клонирует свои выходные данные.

Здесь, когда вы клонируете последовательность с помощью tee() , вы не можете использовать тот же итератор снова. В результате вы должны быть очень осторожны при использовании этой функции!

import itertools

single_iterator = itertools.islice(itertools.count(), 3)
cloned1, cloned2 = itertools.tee(single_iterator)

for num in cloned1:
    print('cloned1: {}'.format(num))
for num in cloned2:
    print('cloned2: {}'.format(num))

Выход

cloned1: 0
cloned1: 1
cloned1: 2
cloned2: 0
cloned2: 1
cloned2: 2

Действительно, мы могли видеть две клонированные последовательности с одинаковыми выходами!

Цикл через последовательности с использованием itertools.cycle()

Функция itertools.cycle() предоставляет итератор, который мы можем использовать бесконечно!

Это полезно, если вы хотите постоянно переключаться между состояниями в своем приложении.

Рассмотрим два состояния лампочки: “включено” и “выключено”.

Вы можете построить итератор, который циклически проходит через два состояния при каждом нажатии переключателя!

import itertools

# Initially, bulb is switched off, so off is the first element in the list
bulb_states = itertools.cycle(["off", "on"])

for _ in range(5):
    # Use next(iterator) to get the current state
    curr_state = next(bulb_states)
    print(f"Bulb state currently {curr_state}")

Выход

Bulb state currently off
Bulb state currently on
Bulb state currently off
Bulb state currently on
Bulb state currently off

Действительно, как вы можете видеть, состояние лампы продолжает циклически переключаться между двумя значениями “включено” и “выключено”!

Фильтруйте элементы с помощью takewhile() и dropwhile()

Мы можем использовать Python itertools.takewhile() функция для фильтрации элементов последовательности до тех пор, пока условие Истинно . Если условие становится False , фильтрация прекращается.

iterator = itertools.takewhile(condition, *sequence)

Вот простой пример, который фильтрует числа, если число положительное.

import itertools

sequence = itertools.takewhile(lambda x: x > 0, [1, 2, 3, -1, 10])

for item in sequence:
    print(item)

Выход

1
2
3

Здесь последовательность остановилась после 3, так как следующий элемент равен -1.

Аналогично, itertools.dropwhile() фильтрует элементы до тех пор, пока условие False и возвращает все элементы после первого значения, не являющегося ложным.

import itertools

data = itertools.dropwhile(lambda x: x < 5, [3, 12, 7, 1, -5])
for item in data:
    print(item)

Выход

12
7
1
-5

Построение комбинаций с использованием комбинаций()

Мы также можем создавать последовательности комбинаций с помощью Python itertools.combinations() .

iterator = itertools.combinations(*sequence, r)

Вот простой пример:

import itertools
words = ['hello', 'from', 'AskPython', 'how']
results = itertools.combinations(words, 2)
for item in results:
    print(item)

Выход

('hello', 'from')
('hello', 'AskPython')
('hello', 'how')
('from', 'AskPython')
('from', 'how')
('AskPython', 'how')

Если вы хотите иметь повторения последовательных элементов в комбинациях, вы можете использовать combinations_with_replacement() .

results = itertools.combinations_with_replacement(words, 3)

for item in results:
    print(item)

Выход

('hello', 'hello', 'hello')
('hello', 'hello', 'from')
('hello', 'hello', 'AskPython')
('hello', 'hello', 'how')
('hello', 'from', 'from')
('hello', 'from', 'AskPython')
('hello', 'from', 'how')
('hello', 'AskPython', 'AskPython')
('hello', 'AskPython', 'how')
('hello', 'how', 'how')
('from', 'from', 'from')
('from', 'from', 'AskPython')
('from', 'from', 'how')
('from', 'AskPython', 'AskPython')
('from', 'AskPython', 'how')
('from', 'how', 'how')
('AskPython', 'AskPython', 'AskPython')
('AskPython', 'AskPython', 'how')
('AskPython', 'how', 'how')
('how', 'how', 'how')

Аналогично, вы можете перечислить перестановки с помощью permutations() и permutations_with_replacement() .

На этом завершаются некоторые важные функции этого модуля. Для получения дополнительных функций вы можете ознакомиться с официальной документацией .

Вывод

В этой статье мы рассмотрели различные функции в модуле Python itertools . В зависимости от вашей проблемы вы можете использовать один из нескольких подходов для быстрого построения последовательностей!

Рекомендации