More itertools

Пакет утилит для манипуляций с итераторами. Дополняет набор из стандартной библиотеке [itertools]. В основном возвращаются итенраторы, генераторы или списки, состоящие из объектов, итераторов или генераторов.

В наборе:

  • chunked() возвращает итератор со списками последовательностей длиной n, сделанной из исходной. Можно поднять ошибку, если список не делится ровно или последний элемент
  • ichunked() возвращает генератор, возвращающий списки
  • sliced() возвращает itertools.takewhile объект. Фактически это список объектов того же типа, что и исходный. Поддерживаются только последовательности, поддерживающие слайсинг. Можно поднять ошибку при неправильной длине
  • distribute() сделать n последовательностей по возможности равно длины. Это может порождать пустые списки. Возвращает список, состоящий из объектов itertools.slice
  • divide() список кортежей-итераторов
  • split_at() разделить последовательность ровно по выбранному объекту (в итоговые последовательности объект не попадает). Возвращается генератор списков. Можно задать максимальное число сплитов. Разделяющий элемент так-же можно сохранять в отдельной последовательности в списке образованных
  • split_before() разделяет последовательность ровно перед позицией разделителя
  • split_after() аналогично
  • split_into() разделить на последовательности длиной, равной переданной в списке длин. Получаем генератор, возвращающий списки
>>> more_itertools.split_into([1,2,3,4,5,6], [1,2,3])
  • split_when() разделяет последовательность в том месте, где выполняется условие для предыдущего значения и последующего. Генератор, который возвращает списки
>>> res = mi.split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], lambda x, y: x > y)
>>> print(list(res))
[[1, 2, 3, 3], [2, 5], [2, 4], [2]]
  • bucket() создает bucket объект, который имеет АПИ словаря. Словарь заполянется так, что ключ - это условие, а значения - все подходящие объекты последовательности. По ключу можно извлекать генераторы последовательностей этих объектов
>>> iterable = ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'b3']
>>> s = mi.bucket(iterable, key=lambda x: x[0])
>>> print(list(s))
['a', 'b', 'c']
>>> print(list(s['b']))
['b1', 'b2', 'b3']
  • unzip() операция обрпатная zip
  • grouper() создает zip_longest() объект из [itertools] зипуя последовательность в группы определенной длины, а нехватающую часть заполяняя филлером
>>> res = mi.grouper('ABCDEFG', 3, 'x')
>>> print(list(res))
[('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]
  • partition() разделяет последовательность по условию так, что слева все что не удовлетворяет, а справа - удовлетворяет условию
  • spy() возвращает список из первых n элементов и итератор всей последовательности
  • peekable() создает итератор и список. Мы можем пикать следующий элемент сколько хотим раз не расходуя итератор или получать элементы последовательности по индексу. Некст передвигает “указатель”. Кроме того можно добавлять элементы в начало итератора
>>> p = mi.peekable(['a', 'b'])
>>> print(p.peek())
a
>>> print(p.peek())
a
>>> print(next(p))
a
>>> p.prepend('12', '13')
>>> print(p.peek())
12
>>> print(next(p))
12
  • seekable() можно ходить по итератору вперед и назад, указывая индекс эелемента. peek() позволяет передвинуться вперед на один айтем без некста итератора. Кеш доступен через elements(), который возвращает уже израсходованные елементы (обновляется один раз, поэтому когда мы передвигаем итератор назад, кеш не обнуляется)

  • github
  • документация