python yield and stopiteration in one loop? python yield and stopiteration in one loop? python python

python yield and stopiteration in one loop?


You seem to be overcomplicating this quite a bit:

>>> q = [1, 2, 3, 4]>>> def gen(header='something', footer='anything'):        yield header        for thing in q:            yield thing        yield footer>>> for tmp in gen():        print(tmp)something1234anything

StopIteration will automatically be raised when a generator stops yielding. It's part of the protocol of how generators work. Unless you're doing something very complex, you don't need to (and shouldn't) deal with StopIteration at all. Just yield each value you want to return from the generator in turn, then let the function return.


Here's a code in which use of StopIteration isn't required, a break is enough:

li = [12,51,98,4,36,99,33,1,125,78,9,369,48,47,214,4]def gen( cont, header='something', footer='anything' ):    yield header    for x in cont:        if x<100:            yield x        else:            yield footer            breakfor y in gen(li):    print '1 or 2 digits only:',y

result

1 or 2 digits only: something1 or 2 digits only: 121 or 2 digits only: 511 or 2 digits only: 981 or 2 digits only: 41 or 2 digits only: 361 or 2 digits only: 991 or 2 digits only: 331 or 2 digits only: 11 or 2 digits only: anything

Now, here's a moderately complex code in which it seems to me that we can't do without use of StopIteration. Does this interest you ?

import Queueq = Queue.Queue()li = [12,51,98,4,36,99,33,1,125,78,9,369,48,47,214,4]def gen( cont, header='something', footer='anything' ):    def qput(ili = [0]):        eli = li[ili[0]]        q.put(eli)        ili[0] = ili[0] + 1        return eli    qput()    qput()    qput()    qput()    qput()    yield header    while True:        try:            print '\nq.qsize() first is %s' % q.qsize()            el = q.get(None)            if el>9:                print 'el==',el                yield 1000+el                qput()            else:                print 'el==%s   el//3==%s' % (el,el//3)                print 'there are %s items in q and q is emptied %s times :' % (q.qsize(),el//3)                for emp in xrange(el//3):                    print '%s is removed from q' % q.get(None)                    if q.qsize()==0 and emp<el//3:                        print 'ah !! q is now completely empty, no more emptying is possible !'            print 'q.qsize() second is %s' % q.qsize()        except Queue.Empty:            yield footer            raise StopIterationprint 'li == %s\n' % lifor i,nb in enumerate(gen(li)):    print ' * obtained from enumerate(gen(li)) : %s - %s' % (i,nb)

result

li == [12, 51, 98, 4, 36, 99, 33, 1, 125, 78, 9, 369, 48, 47, 214, 4] * obtained from enumerate(gen(li)) : 0 - somethingq.qsize() first is 5el== 12 * obtained from enumerate(gen(li)) : 1 - 1012q.qsize() second is 5q.qsize() first is 5el== 51 * obtained from enumerate(gen(li)) : 2 - 1051q.qsize() second is 5q.qsize() first is 5el== 98 * obtained from enumerate(gen(li)) : 3 - 1098q.qsize() second is 5q.qsize() first is 5el==4   el//3==1there are 4 items in q and q is emptied 1 times :36 is removed from qq.qsize() second is 3q.qsize() first is 3el== 99 * obtained from enumerate(gen(li)) : 4 - 1099q.qsize() second is 3q.qsize() first is 3el== 33 * obtained from enumerate(gen(li)) : 5 - 1033q.qsize() second is 3q.qsize() first is 3el==1   el//3==0there are 2 items in q and q is emptied 0 times :q.qsize() second is 2q.qsize() first is 2el== 125 * obtained from enumerate(gen(li)) : 6 - 1125q.qsize() second is 2q.qsize() first is 2el== 78 * obtained from enumerate(gen(li)) : 7 - 1078q.qsize() second is 2q.qsize() first is 2el==9   el//3==3there are 1 items in q and q is emptied 3 times :369 is removed from qah !! q is now completely empty, no more emptying is possible ! * obtained from enumerate(gen(li)) : 8 - anything

Note that this program runs correctly only with q.get(None) , not q.get()


I come from the future. I recommend yield from:

def gen(q, header="header", footer="footer"):    yield header    yield from q    yield footer

Output:

>>> g = gen([1, 2, 3, 4])>>> print(*g, sep="\n")header1234footer