Итеративность в Python

Я пытаюсь понять Iterability в Python.

Как я понимаю, __iter__() должен возвращать объект, у которого есть метод next(), который должен возвращать значение или поднять исключение StopIteration. Таким образом, я написал этот класс, который удовлетворяет обоим этим условиям.

Но это не работает. Что не так?

class Iterator:
    def __init__(self):
        self.i = 1

    def __iter__(self):
        return self

    def next(self):
        if self.i < 5:
            return self.i
        else:
            raise StopIteration

if __name__ == __main__:
    ai = Iterator()
    b  = [i for i in ai]
    print b

Ответы

Ответ 1

Ваш текущий код работает. Вместо этого я покажу вам еще несколько итераторов/генераторов.

самый простой встроенный с вашим поведением.

Iterator2 = xrange(2,5)

Прямой перевод вашего класса в генератор

def Iterator3():
    i = 1
    while i < 5:
        i += 1
        yield i

генератор, составленный из генераторов в стандартной библиотеке python

import itertools
Iterator4 = itertools.takewhile( 
                        lambda y : y < 5, 
                        itertools.count(2) )

простое выражение генератора (не очень возбуждающее...)

Iterator5 = ( x for x in [2, 3, 4] )

Ответ 2

Ваш класс Iterator верен. У вас просто опечатка в этом утверждении:

if __name__ ==' __main__':

В строке '__main__' есть ведущее пробеливание. Вот почему ваш код вообще не выполняется.

Ответ 3

i никогда не станет больше 5, если вы не увеличите его в next()

Ответ 4

Я думаю, что в большинстве случаев может быть достаточно написать функцию генератора которая использует yield вместо написания полноценного итератора.

Ответ 5

В вашем коде две проблемы:

  • if name == '__main__': (отсутствующие кавычки)
  • def next . . .: вы не увеличиваете i в любом месте