4

I am trying to understand Iterability in Python.

As I understand, __iter__() should return an object that has next() method defined which must return a value or raise StopIteration exception. Thus I wrote this class which satisfies both these conditions.

But it doesn't seem to work. What is wrong?

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
Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
lprsd
  • 84,407
  • 47
  • 135
  • 168

5 Answers5

9

Your Iterator class is correct. You just have a typo in this statement:

if __name__ ==' __main__':

There's a leading whitespace in the ' __main__' string. That's why your code is not executed at all.

Haes
  • 12,891
  • 11
  • 46
  • 50
4

i will never become greater than 5 if you don't increment it in next()

cobbal
  • 69,903
  • 20
  • 143
  • 156
4

I think in most cases it might be enough to write a generator function that uses yield instead of writing a full-fledged iterator.

Michael Kuhn
  • 8,302
  • 6
  • 26
  • 27
1

Your current code seems to work. Instead i'll show you some more iterators/generators.

the simplest builtin with exactly your behavior.

Iterator2 = xrange(2,5)

A direct translation of your class to a generator

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

a generator composed from generators in the python standard library

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

a simple generator expression (not very exciting...)

Iterator5 = ( x for x in [2, 3, 4] )
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
0

Your code has two problems:

  • if name == '__main__': (missing quotes)
  • def next . . .: you don't increment i anywhere
Ethan Furman
  • 63,992
  • 20
  • 159
  • 237