Overload __iter__ method to create Iterator

Overload __iter__

The magic method, __iter__, is the basis of the iterator protocol.

The __iter__ method returns an iterator, which is any object with a method called next, which is callable without any arguments.

When you call the next method, the iterator should return its "next value." If the method is called, and the iterator has no more values to return, it should raise a StopIteration exception.


class Fibs: # from   www. jav a2  s  . c o  m
    def __init__(self): 
        self.a = 0 
        self.b = 1 
    def next(self): 
        self.a, self.b = self.b, self.a+self.b 
        return self.a 
    def __iter__(self): 
        return self 

fibs = Fibs() 
for f in fibs: 
   if f > 1000: 
      print f 
      break 
      

The code above generates the following result.

An object that implements the __iter__ method is iterable, while the object implementing next is the iterator.

__iter__ method provides protocol for iterator. We can provide custom implementation for __iter__ to create our own iterator.

The code above creates a Fibonacci numbers iterator.


class FileList:# ww  w  .j  a v a  2  s .c  om
    def __init__(self):
        self.ptr = 0
        self.file_list = ["file1", "file2", "file3", "file4" ]
    def __iter__(self):
        self.ptr = 0
        return self
    def next(self):
        if self.ptr == len(self.file_list):
           raise StopIteration
        s = self.file_list[self.ptr]
        self.ptr = self.ptr + 1
        return s

fl = FileList()
for f in fl :
    print f
    

The code above generates the following result.

Making Sequences from Iterators

We can convert iterators to sequences.


class TestIterator: 
    value = 0 #   w  w w . j a  v  a  2s . co  m
    def next(self): 
        self.value += 1 
        if self.value > 10: raise StopIteration 
        return self.value 
    def __iter__(self): 
        return self 

ti = TestIterator() 
print list(ti) 

The code above generates the following result.

Add iterator behavior to your classes

The following code defines a __iter__() method which returns an object with a next() method. If the class defines next(), then __iter__() can just return self:


class Reverse:#   w ww  .ja v a  2s  .  c  om
    "Iterator for looping over a sequence backwards"
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def next(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

for char in Reverse('spam'):
     print char

The code above generates the following result.





















Home »
  Python »
    Language Basics »




Python Basics
Operator
Statements
Function Definition
Class
Buildin Functions
Buildin Modules