Subject: Available (250K) - May 2014

From: At Risk of Expiration <[email-masked]>
Date: Fri, 09 May 2014 11:08:00 -0700

Notification Generated for: Ietf-dkim-archive

Recent Findings: 

You may qualify for a low Term-Life Rate.
-------------------------------------------
- This means 250,000K+ is immediately available -  

View New Rate Here: / http://www.suchvis.com/policy/terms/update/id034.index
[Rate Generated on: May 9, 2014]

Rapid Response is the recommended action for this situation. 

Regards,

Urgent Info Services
http://www.suchvis.com/policy/terms/update/id034.index

-to modify settings w/ Urgent Info Services 
3205 Lake Sarah Independence, MN 5 5 3 5 9 
or visit http://www.suchvis.com/kgvk3.fk3oos

Instead of yield statements, if you had three return statements in f123() only the first would get executed, and the function would exit. But f123() is no ordinary function. When f123() is called, it does not return any of the values in the yield statements! It returns a generator object. Also, the function does not really exit - it goes into a suspended state. When the for loop tries to loop over the generator object, the function resumes from its suspended state, runs until the next yield statement and returns that as the next item. This happens until the function exits, at which point the generator raises StopIteration, and the loop exits.

So the generator object is sort of like an adapter - at one end it exhibits the iterator protocol, by exposing __iter__() and next() methods to keep the for loop happy. At the other end however, it runs the function just enough to get the next value out of it, and puts it back in suspended mode.

Why Use Generators?

Usually you can write code that doesn't use generators but implements the same logic. One option is to use the temporary list 'trick' I mentioned before. That will not work in all cases, for e.g. if you have infinite loops, or it may make inefficient use of memory when you have a really long list. The other approach is to implement a new iterable class SomethingIter that keeps state in instance members and performs the next logical step in it's next() (or __next__() in Python 3) method. Depending on the logic, the code inside the next() method may end up looking very complex and be prone to bugs. Here generators provide a clean and easy solution.class it:
    def __init__(self):
        #start at -1 so that we get 0 when we add 1 below.
        self.count = -1
    #the __iter__ method will be called once by the for loop.
    #the rest of the magic happens on the object returned by this method.
    #in this case it is the object itself.
    def __iter__(self):
        return self
    #the next method will be called repeatedly by the for loop
    #until it raises StopIteration.
    def next(self):
        self.count += 1
        if self.count < 4:
            return self.count
        else:
            #a StopIteration exception is raised
            #to signal that the iterator is done.
            #This is caught implicitly by the for loop.
            raise StopItera