[Tutor] Generator questions.

wesley chun wescpy at gmail.com
Wed Dec 6 21:53:36 CET 2006


> def lines(file):
>    for line in file: yield line
>    yield '\n'
>
> del blocks(file):
>    block = []
>    for line in lines(file):
>        if line.strip():
>           block.append(line)
>        elif block:
>           yield ''.join(block).strip()
>           block = []
>
> 1.) Does the yield mean the block list is returned from the function
> AND then wiped out by 'block = []'?

the code in question will take all the strings in block, concatenate
them together [with ''.join()], remove leading/trailing whitespace
[.strip()], and yield or "return" it as the next "generated" item
being iterated over.  when .next() is executed again, either
explicitly by the caller or via a for-loop, it will resume immediately
on the next line succeeding the yield statement where execution was
paused.


> 2.) Is block list scrubbed clean by 'block = []' because the function
> is going to iterate over the next block and it needs to be empty?

yes, block is then cleared so that it can process the next few lines of data.


> 3.) The statement after the 'yield' threw me. I haven't seen that to
> this point in the book. I figured 'yield' is always last in a function
> because it needs to iterate over itself again. Am I understanding
> generators correctly?

a "yield" does *not* have to be the last in the function.  wherever a
yield is encountered, the function will resume right after it when
.next() is called again.  generators do "not start from scratch...,"
they pick up right where they left off.


> 4.) Is it correct to say that a generator is a function that returns
> multiple values and iterates over itself?

a generator acts like an iterator in that multiple values are returned
in an iterative process (meaning not all at the same time).  it is
dressed up as a function which contains logic that can "generate" each
successive value to "return."

i have to give kudos to magnus for putting "real world" code when he
teaches generators in his book.  for my core python book, i was more
concerned about getting the point across as to what generators *are*,
so for completeness, here are some of the examples i used, all of
which can be downloaded at the book's website (see below) regardless
of whether you buy the book (or not):

1) simpleGen.py (the world's 2nd simplest generator?):

def simpleGen():
    yield 1
    yield '2 --> punch!'

if __name__ == '__main__':
    for item in simpleGen():
        print item

2) randGen.py:

from random import randrange as rr

def randGen(aList):
    while aList:
        yield aList.pop(rr(len(aList)))

if __name__ == '__main__':
    for item in randGen(['rock', 'paper', 'scissors']):
        print item

3) counter.py (needs 2.5+):

def counter(start_at=0):
    count = start_at
    while True:
        val = (yield count)
        if val is not None:
            count = val
        else:
            count += 1

if __name__ == '__main__':
    print 'initializing counter to start counting at 5'
    count = counter(5)
    print 'calling count.next():', count.next()
    print 'calling count.next():', count.next()
    print 'calling count.send(9):', count.send(9)
    print 'calling count.next():', count.next()
    print 'calling count.close():', count.close()
    print 'calling count.next():', count.next()

you can get these by clicking on "Source Code" -> ch11 -> alt. i'll
leave it as an exercise to reader to determine the output *and WHY*.
:-) another fun place to go look for iterators is the itertools
module.  it contains a lot of useful iteration code that are all
really just generators(!):

http://docs.python.org/lib/itertools-functions.html

hope this helps!
-- wesley
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Core Python Programming", Prentice Hall, (c)2007,2001
    http://corepython.com

wesley.j.chun :: wescpy-at-gmail.com
python training and technical consulting
cyberweb.consulting : silicon valley, ca
http://cyberwebconsulting.com


More information about the Tutor mailing list