Я заметил, что редко использую функции из
Сам модуль itertools это набор из эффективных и быстрых по памяти инструментов, возвращающие итераторы. Сами по себе итераторы можно комбинировать с такими функциями как
А сегодня мы начнем c самых простых - c бесконечных итераторов. Всего по документации их три:
Ниже я буду указывать аргументы по умолчанию и возможные передаваемые типы как тайп-хинты. Надеюсь ни у кого не возникнет проблем с пониманием.
#itertools #std
itertools
, в основном когда нужно произвести какие-то "красивые" шаманства. Теперь будем вспоминать саму библиотеку вместе, естественно с примерами :)Сам модуль itertools это набор из эффективных и быстрых по памяти инструментов, возвращающие итераторы. Сами по себе итераторы можно комбинировать с такими функциями как
map()
, list()
лямбдами или же использовать их с помощью цикла for. А сегодня мы начнем c самых простых - c бесконечных итераторов. Всего по документации их три:
count()
, cycle()
и repeat()
.Ниже я буду указывать аргументы по умолчанию и возможные передаваемые типы как тайп-хинты. Надеюсь ни у кого не возникнет проблем с пониманием.
#itertools #std
Коробка с питоном
Я заметил, что редко использую функции из itertools, в основном когда нужно произвести какие-то "красивые" шаманства. Теперь будем вспоминать саму библиотеку вместе, естественно с примерами :) Сам модуль itertools это набор из эффективных и быстрых по памяти…
count(start: int | float = 0, step: int | float = 1) -> Iterator[int | float]
Создает итератор, который возвращает равномерно распределенные значения, начиная с числа, указанного в аргументе start. Само значение-шаг указывается в переменной step:>>> first = count(10, 2)Небольшая загадка для вас - почему вместо 0.3 получили такое число? Пишите в комменты :)
>>> next(first)
10
>>> next(first)
12
>>> next(first)
14
>>> second = count(0.1, 0.1)
>>> next(second)
0.1
>>> next(second)
0.2
>>> next(second)
0.30000000000000004
>>> next(second)
0.4
#itertools #std
Коробка с питоном
Я заметил, что редко использую функции из itertools, в основном когда нужно произвести какие-то "красивые" шаманства. Теперь будем вспоминать саму библиотеку вместе, естественно с примерами :) Сам модуль itertools это набор из эффективных и быстрых по памяти…
cycle(p: Iterable) -> Iterator
Создает итератор, который возвращает элементы из переданного итератора поштучно и сохраняет их. После того как элементы закончились, он начинает возвращать сохранённые элементы и так до тех пор, пока мы сами не прервем его работу: >>> first = cycle([1, 2])Например, вот так при помощи функций islice и cycle мы можем сгенерировать список из 20 элементов из необходимой нам коллекции:
>>> next(first)
1
>>> next(first)
2
>>> next(first)
1
>>> next(first)
2
>>> list(islice(cycle([1, 2, 3, 4]), None, 20))
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
#itertools #std
Коробка с питоном
Я заметил, что редко использую функции из itertools, в основном когда нужно произвести какие-то "красивые" шаманства. Теперь будем вспоминать саму библиотеку вместе, естественно с примерами :) Сам модуль itertools это набор из эффективных и быстрых по памяти…
repeat(object: T, times: Optional[int] = None) -> Iterable[T]
Создает итератор который возвращает объект снова и снова. Можно указать параметр times, который вернет объект заданное количество раз и завершит работу итератора:>>> first = repeat("hehe", 3)Очень часто repeat используют чтобы по быстрому сгенерировать коллекцию из элементов:
>>> next(first)
'hehe'
>>> next(first)
'hehe'
>>> next(first)
'hehe'
>>> next(first)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> list(repeat(10, 10))#itertools #std
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
Если обычного itertools вам мало, то можно использовать more-itertools.
Эта библиотека добавляет огромное количество функций для работы с итераторами. На практике всеми ими не всегда пользуются, поэтому я выделю некоторые из тех, которые сам использую часто.
Например, вот так можно разделить список на 3 части:
Решим самую частую проблему - перевести список с несколькими уровнями вложенностями в "плоский" список:
PyPI | Документация
#more_itertools #itertools #библиотека #рецепт
Эта библиотека добавляет огромное количество функций для работы с итераторами. На практике всеми ими не всегда пользуются, поэтому я выделю некоторые из тех, которые сам использую часто.
Например, вот так можно разделить список на 3 части:
data = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh"]Вот еще задача. Надо разделить список с элементами по определенному условию. В этом нам поможет
[list(l) for l in divide(3, data)]
# [['first', 'second', 'third'], ['fourth', 'fifth'], ['sixth', 'seventh']]
bucket
:class Cat:По итогу кошки и собаки будут разделены по своему типу на 2 генератора.
pass
class Dog:
pass
shapes = [Cat(), Dog(), Cat(), Dog(), Cat(), Cat()]
result = more_itertools.bucket(shapes, key=lambda x: type(x))
len(list(result[Cat])) # 4
len(list(result[Dog])) # 2
Решим самую частую проблему - перевести список с несколькими уровнями вложенностями в "плоский" список:
iterable = [(1, 2), ([3, 4], [[5], [6]])]А если в плоский список нам нужно вытащить только элементы с первым уровнем вложенности?
list(more_itertools.collapse(iterable)) #[1, 2, 3, 4, 5, 6]
list(more_itertools.collapse(iterable, levels=1)) # [1, 2, [3, 4], [[5], [6]]]А вот так мы можем посмотреть, все ли элементы в коллекции уникальные:
more_itertools.all_unique([1, 2, 3, 4]) # TrueБиблиотека решает очень много типовых проблем, поэтому если научиться ей пользоваться - она сэкономит очень много времени. Возможно, я еще буду писать какие-то рецепты с ней, но это не точно 🌚...
more_itertools.all_unique([1, 2, 1, 4]) # False
PyPI | Документация
#more_itertools #itertools #библиотека #рецепт
PyPI
more-itertools
More routines for operating on iterables, beyond itertools
Коробка с питоном
Если обычного itertools вам мало, то можно использовать more-itertools. Эта библиотека добавляет огромное количество функций для работы с итераторами. На практике всеми ими не всегда пользуются, поэтому я выделю некоторые из тех, которые сам использую часто.…
На сегодня расскажу ещё пару рецептов с
1)
2) Получить последний элемент можно при помощи
Ещё есть
3)
4) Ну и в конце про
#itertools #more_itertools #библиотека #рецепт
more_itertools
.1)
map_if
работает как обычный map
, но применяет функцию на элемент только если оно попадает под условие. Например, вот так мы можем возвести в квадрат только те числа, которые делятся на 2 нацело:example = [1, 2, 3, 4, 5, 6, 7, 8]
list(map_if(example, lambda x: x % 2 == 0, lambda x: x * x)) # [1, 4, 3, 16, 5, 36, 7, 64]
2) Получить последний элемент можно при помощи
last
. Возникает вопрос а зачем он существует, если можно указать sequence[-1]
? Ответом является то, что last
позволяет указать, что ему возвращать, если элементов в коллекции нет:last([1, 2, 3]) # Очевидно получим 3
last([], 0) # Список пустой, но получим 0
[][-1] # Получим IndexError
Ещё есть
first
- как понятно из названия, он получает первый элемент.3)
map_except
тоже работает как map
, но умеет игнорировать ошибки. Например, мы хотим получить только те элементы, которые получилось привести к целому числу:example = [1, "1", "2", "test", "three", object, 4.0]
list(map_except(int, example, ValueError, TypeError)) # [1, 1, 2, 4]
4) Ну и в конце про
take
- он просто берет N элементов из итерируемого объекта:example = range(10)
take(3, example) # [0, 1, 2]
take(20, example) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - если больше, возьмет доступные
#itertools #more_itertools #библиотека #рецепт