python yield and stopiteration in one loop?

yee379 picture yee379 · Jul 22, 2011 · Viewed 38.6k times · Source

i have a generator where i would like to add an initial and final value to the actual content, it's something like this:

# any generic queue where i would like to get something from
q = Queue()

def gen( header='something', footer='anything' ):
    # initial value header
    yield header

    for c in count():
        # get from the queue
        i = q.get()
        # if we don't have any more data from the queue, spit out the footer and stop
        if i == None:
            yield footer
            raise StopIteration
        else:
            yield i

Of course, the above code doesn't work - my problem is that i would like it such that when there's nothing left in the queue, i want the generator to spit out the footer AND raise the StopIterator. any ideas?

Cheers,

Answer

Ben picture Ben · Jul 22, 2011

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)


something
1
2
3
4
anything

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.