Комментарии 18
product
еще удобно использовать для генерации тест-кейсов. В pytest
для этого можно можно стековать декораторы pytest.mark.parametrize
P.S. Картинки к статьям зачетные
The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using
zip(*[iter(s)]*n, strict=True)
. This repeats the same iteratorn
times so that each output tuple has the result ofn
calls to the iterator. This has the effect of dividing the input into n-length chunks. https://docs.python.org/3.11/library/functions.html#zip
a = [1, 2, 3, 4, 5, 6]
list(zip(*[iter(a)]*3))
[(1, 2, 3), (4, 5, 6)]
Вопрос к началу статьи. А что другие языке сейчас этого не умеют делать? Я спокойно тоже самое могу делать на C#, Lua, Delphi, Basic ...
В таком случае вы сможете написать по статье для каждого из вышеупомянутых языков и об особенностях использования итераторов и генераторов в них. Уверен, там достаточно дьяволов в деталях, чтобы это стало интересным.
Редкий случай, когда статья оказалась лучше, чем то, что я ожидал, исходя из названия.
Хорошая статья, всегда полезно такие вещи перечитывать даже когда вроде и шаришь и юзаешь давно и плотно, но нет-нет да и находится какая-то фишка или пояснение, нечто, на что ранее не обращал внимание или с чем не доводилось столкнуться.
Кстати, функция iter() с аргументом sentinel еще может быть полезна для организации длинных циклов заранее неизвестной длины с постусловием для выхода и использованием номера итерации внутри, вроде такого:
for idx, _ in enumerate(iter(int, 1)):
... # doing something
Фишка тут в том, что int() всегда возвращает ноль, поэтому стоп-слова терминального символа встречено не будет.
А знаете ли вы ещё какие-нибудь интересные примеры итераторов и итерируемых объектов в стандартной библиотеке Python?
Обильное использование итераторов в коде, создаёт последующим поколениям разработчиков, кто будет заниматься сопровождением, множество не только увлекательных, но и не тривиальных задач. Как раз таких, про которые мы часто пишем в своих резюме.
fizzbuzzes = islice(zip(numbers, fizzes, buzzes), 100)
В отличие от хаскелей, где декларативный код хорошо оптимизируется, итераторы в питоне создают овехед из-за необходимости вызвать дополнительные методы. Накладные расходы для передачи значения внутри длинных цепочек вложенных итераторов может оказаться больше, чем само вычисление.
Переписывание кода на традиционные циклы, зачастую не только возвращает вам понятные стектрейсы в случае ошибок, возможность отладки в дебагере по шагам, но и делает его быстрее.
В целом, про простоту и скорость согласен. В примере с fizzbuzz - это просто иллюстрация возможностей модуля itertools и итераторов, а не рекомендация все циклы в коде заменять на итераторы. В каких-то случаях итераторы могут улучшить читаемость кода, в каких-то, наоборот, могут ухудшить.
Читаемость это важное свойство. Не сочтите за критику, у вас классная статья с выразительными примерами.
fizzbuzzes = islice(zip(numbers, fizzes, buzzes), 100)
Если рассматривать данную конкретную строку, то я не представляю как её можно понятнее переписать. Да, последующим поколениям разработчиков возможно придётся заглянуть в документацию по стандартной библиотеке.
Тема конечно философская. Читабельность это не только про возможность специалисту разобраться как работает код. В идеале, глядя на код вы должны понимать исходную постановку задачи - что он должен делать. Одно из следствий - такой код проще поддерживать (не требуется отдельно писать документацию) и расширять (требования обычно меняются в тех же терминах, что и исходная постановка, значит код проще дорабатывать и верифицировать когда он написан в тех же терминах и общей логике).
если число делится нацело на 3, то вместо самого числа нужно вывести строку fizz, если же число делится нацело на 5, то нужно вывести строку buzz. Ну а если число делится нацело и на 3, и на 5, то на экран нужно вывести fizzbuzz
Здесь задача поставлена императивно. Поэтому реализация в виде кальки с if-else будет, на мой взгляд, наилучшей. Решение на итераторах элегантно остроумно. Но по сути это запись решения некоей эквивалентной задачи, поэтому оно довольно хрупкое. Глядя на код декомпилировать исходную постановку уже проблематично. Добавление новых условий в задачу сделает его или ещё более не эффективным или вообще заставит переписать целиком. Поэтому я сомневаюсь относительно читабельности.
10 итераторов, о которых вы могли не знать