[Tutor] Iterators and Generators...

Marc Barry marc_barry at hotmail.com
Thu Aug 14 03:33:04 EDT 2003


Everyone, thanks for the help.  I was confused with what the yield statement 
in a function actually did.  I was trying to implement the iterator protocol 
and therefore I thought that I had to define two methods; __iter__ and 
next() (which is true).  But, I thought that the 'yield' statement just 
returned its value and upon calling the method/function another time would 
resume after the 'yield' statement.  So my confusion was that I did't know 
that a function or method with a yield statement returns a generator (which 
already implements the iterator protocol).  Just calling the next() method 
executes the method or function up to the yield statement and then returns 
the value (whilst preserving the state of the method/function).

So, alles klar -> As pointed out below, there is no need to call the next() 
method in my class as I could just put all the code from the next method 
into the __iter__ method.

I have a question, why didn't Python just cause a method with a 'yield' 
statement to return its value and preserve its state.  Then, upon subsequent 
calls to the method it could begin execution from the point it left off.  
Basically, I am asking why they didn't choose the above option and chose to 
return a generator (i.e. build the object for you) instead?  With the above 
option, a person could easily implement the iterator protocol and there is 
no need for a generator.

Regards,

Marc


From: Neil Schemenauer <nas-pytut at python.ca>
To: tutor at python.org
Subject: Re: [Tutor] Iterators and Generators...
Date: Wed, 13 Aug 2003 09:24:26 -0700

Karl Pfl?sterer wrote:
 > You never called your next() method (and you have a typo); I underlined
 > both in your example.
 >
 > So the correct code would be:
 >
 > class list_iterator:
 >         def __init__(self, a_list):
 >                 self.a_list = a_list
 >
 >         def __iter__(self):
 >                 return self.next()
 >
 >         def next(self):
 >                 for i in self.a_list:
 >                         yield i
 >                 raise StopIteration

Yikes.  There's no need to explicitly raise StopIteration.  Also, the
'next' method could be called anything.  Don't get confused that the
name is somehow special.  For example, the following code does exactly
the same thing:

class list_iterator:
         def __init__(self, a_list):
                 self.a_list = a_list

         def __iter__(self):
                 return self.pumpkin()

         def pumpkin(self):
                 for i in self.a_list:
                         yield i

Furthermore, you don't need the extra method if you put the yield loop
in the __iter__ method.

   Neil

_______________________________________________
Tutor maillist  -  Tutor at python.org
http://mail.python.org/mailman/listinfo/tutor

_________________________________________________________________
The new MSN 8: smart spam protection and 2 months FREE*  
http://join.msn.com/?page=features/junkmail




More information about the Tutor mailing list