Если вы когда-нибудь работали с последовательностями, вы почти наверняка сталкивались с ситуацией: нужно пройтись не по одному элементу, а по соседним. Для таких случаев в Python есть замечательная штука —
itertools.pairwise.Она берёт ваше
"ABCD" и превращает это в:("A", "B"), ("B", "C"), ("C", "D")Звучит просто — и это реально спасает в куче сценариев. Например, можно легко посчитать, как менялся банковский баланс:
from itertools import pairwise
balance_history = [700, 1000, 800, 750]
for before, after in pairwise(balance_history):
print(after - before)
Но фокус вот в чём…
Иногда пары — это мало. Хочется тройки, четвёрки, пятёрки… словом, окно произвольного размера.
Вот здесь
pairwise уже не поможет — поэтому мы собрали несколько аккуратных способов сделать «обобщённый pairwise», он же nwise().✔️ Вариант 1 — через deque
Простой, понятный и работает на всём, что итерируется:
from collections import deque
from itertools import islice
def nwise(iterable, n):
iterable = iter(iterable)
window = deque(islice(iterable, n - 1), maxlen=n)
for value in iterable:
window.append(value)
yield tuple(window)
Использование:
nwise("ABCD", 3)
→ ("A","B","C"), ("B","C","D")✔️ Вариант 2 — через tee
Такой «фокус с зеркалами»: создаём n независимых итераторов и сдвигаем каждый на свою позицию:
from itertools import islice, tee
def nwise(iterable, n):
iterators = tee(iter(iterable), n)
for idx, iterator in enumerate(iterators):
for _ in islice(iterator, idx):
pass
yield from zip(*iterators)
Выглядит почти магически, но работает честно.
✔️ Вариант 3 — рекурсивный (красивый)
Пожалуй, личный фаворит. Если присмотреться, можно заметить:
triplewise — это просто pairwise(pairwise(...)).А значит, можно сделать рекурсию:
from itertools import pairwise
def nwise(iterable, n):
if n == 1:
yield from ((x,) for x in iterable)
return
for (head, *_), tail in pairwise(nwise(iterable, n - 1)):
yield (head, *tail)
Минимализм и элегантность.
🍷 Если вдруг придумаете способ лучше — пишите!
🔹 Курс «Программирование на языке Python»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
🐸 Библиотека питониста
#буст
