Чем Генераторы отличаются от Итераторов в Python?

preview_player
Показать описание
Частый вопрос - в чем разница между генераторами и итераторами? Давайте разберемся на примере!

Канал создан при поддержке сообщества Moscow Python.
Рекомендации по теме
Комментарии
Автор

Тут всё-таки реально просится упоминание ещё и про Iterable, а не только про Iterator.

Iterable и Iterator – это «протоколы», правила. Как именно и что именно ты должен написать в классе, чтобы сделать его «итерируемым».

Между ними есть тонюсенькая, но важная разница. Iterable – в переводе, «итерируемый» – это свойство того, по кому будем итерироваться. Представьте, что вы пишете логику хождения по файловой системе, или логику того, как паук-краулер облазивает весь интернет. Iterable, «итерируемой сущностью» в этих случаях будет то, «что итерируемо».
Файловая система – итерируема? Да, по ней можно итерироваться. Интернет – итерируем? – да, по нему можно «ползать». Именно он и есть Iterable; именно он и реализует метод __iter__.

Iterator – в переводе, это «итерирующий». В нашем случае эти два класса совпадают, и получается слегка запутанно. Но это вовсе не обязательно. Итератор – это «тот, кто ходит». Отслеживает текущее состояние. В терминах БД это часто называется «курсором». Этот объект может отличаться от iterable и должен реализовывать метод __next__. И именно этот объект, вероятно, будет возвращать метод __iter__ из предыдущего абзаца.

Итак, всё просто. Iterable – сущность, по которой ходим. Книга, которую листаем. Iterator – листающая сущность. Палец, который указывает на нужный лист в книге. И оба – это всего лишь «наборы правил, как реализовывать итерацию средствами Питона».

Генератор же – немножко интереснее. Это не протокол, а конкретная реализация. Это хитрый механизм в Питоне, который позволяет тебе сделать однократно перебираемую функцию, логика перебора которой легко и красиво описывается. Ты в цикле описываешь процесс генерации каждого элемента, но не считаешь каждый последующий элемент до тех пор, пока он тебе не потребуется. А может быть, он и не потребуется вовсе.
Этакий «ленивый итератор», в программистском понимании слова «ленивый» (lazy). Ты описал правило формирования каждого элемента – но формируешь его только тогда, когда его запросят (потому что «считать заранее тебе лень»). А главное – способный к шикарной работе, принимая такие же генераторы (или какие-то другие итераторы) на вход. Ими можно описывать даже бесконечные последовательности – а какая разница, всё равно считаться и перебираться они будут только по одному элементу.

Но это не «протокол», не правило реализации. А, повторюсь – встроенная в язык конкретная особенность, можно было бы даже сказать «структура данных» (только это не структура хранения данных, а скорее структура алгоритмической работы с ними). «Есть списки, есть словари, а есть итераторы».

amyodov
Автор

В чем разница между итератором и генератором ? Чтобы написать итератор требуется больше кода! Гениальное объяснение )

mantrida
Автор

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

SamurayXXI
Автор

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

Zulya
Автор

еще можно преобразовать объект в итератор при помощи iter() и пройтись по нему, используя next()

userunknown
Автор

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

dynjcdd
Автор

2:29 Пазишн намбер уан - отдыхаю сам )

dwvdxfr
Автор

Слышал где-то, что функция len бесплатная(не расходует ресурсы)

alexey
Автор

Не совсем понял, а зачем собственно писать целый класс для итерации по строке? Если можно просто проитерироваться по строке в цикле for и возвращать тоже самое что в генераторе, только без создания самого генератора)

ukdkbbj
Автор

Офигенное объяснение. Большое спасибо за видео!

PsdmasterRu
Автор

В классе итератора ошибка, он получился одноразовый.
И в принципе зачем было создавать итератор через класс, вот отличны итератор:
for char in 'string':
print(char.upper())

eugenebybin