[Tutor] generators and classes

Marilyn Davis marilyn at deliberate.com
Tue Feb 24 02:54:33 EST 2004


Thank you for this.

On Tue, 24 Feb 2004, Lloyd Kvam wrote:

> In the first example, you call list_unique which handles the
> looping, calls the generator, and returns a list.  The class example
> puts the looping in the caller and never builds a list.  Put unique
> and list_unique methods into the class and I think it will work more
> like the first example.

I'm just thinking that maybe the generator facility doesn't make sense
in a class structure --> because the initializing part of the
generator function belongs in __init__ and then you want the yield to
be in another function because __init__ isn't allowed to return
anything.  So, you already have two functions with shared scope so you
might as well return, skip the next(), and keep things simple.

I tried to do what you suggest and it gets clumsy (but it works!).

Maybe you intended something different?

#! /usr/bin/python2.2
'''
Demonstrates generators and the 'yield' keyword in the
context of a class structure.'''

from __future__ import generators
import random

class Scrambler:
    '''Generator to deliver randomly chosen values from bot
    to over_top - 1, delivering each value once only.  To
    collect the numbers, you make an object and call:
    object.take.next()'''
    def __init__(self, bot, over_top):
        self.bot = bot
        self.over_top = over_top
        self.taken = [0] * (over_top - bot)
        self.take = self.dummy()

    def dummy(self):
        while 1:
            give = random.randrange(self.bot, self.over_top) 
            if not self.taken[give - self.bot]:
                self.taken[give - self.bot] = 1
                yield give

if __name__ == '__main__':
    scram = Scrambler(0,10)
    for i in range(10):
        print scram.take.next()

#############################
# OUTPUT:
# bash-2.05a$ ./scrambler.py
# 3
# 4
# 8
# 2
# 7
# 1
# 6
# 0
# 9
# 5
# bash-2.05a$ 

----
> 
> Marilyn Davis wrote:
> 
> > Hello again,
> > 
> > I wrote this little program to demonstrate a generator:
> > 
> > #! /usr/bin/python2.2
> > '''Function to generate random numbers without repetition.
> > Demonstrates generators and the 'yield' keyword.'''
> > 
> > from __future__ import generators
> > import random
> > 
> > def unique(bot, over_top):
> >     '''Generator to deliver randomly chosen values from bot
> >     to over_top - 1, delivering each value once only.'''
> >     taken = [0] * (over_top - bot)
> >     while (1):
> >         give = random.randrange(bot, over_top) 
> >         if not taken[give - bot]:
> >             taken[give - bot] = 1
> >             yield give
> > 
> > def list_unique(bot, over_top):
> >     '''Returns a list of the generated numbers'''
> >     gen = unique(bot, over_top)
> >     return [gen.next() for i in range(bot, over_top)]
> > 
> > if __name__ == '__main__':
> >     print '(0,5) = ', list_unique(0,5)
> >     print '(10,21) = ', list_unique(10,21)
> > 
> > #############################
> > # OUTPUT:
> > # bash-2.05a$ ./unique.py
> > # (0,5) =  [2, 3, 1, 0, 4]
> > # (10,21) =  [17, 10, 18, 20, 19, 15, 11, 13, 12, 16, 14]
> > # bash-2.05a$     
> > 
> > -----
> > 
> > But now that I'm preparing to teach OO, I want to do the class
> > equivalent, which turns out like this:
> > 
> > #! /usr/bin/env python2.2
> > 
> > import random
> > 
> > class NumberHat:
> >     '''Generator to deliver randomly chosen values from bot
> > to over_top - 1, delivering each value once only.'''
> >     def __init__(self, bot, over_top):
> >         self.bot = bot
> >         self.over_top = over_top
> >         self.taken = [0] * (over_top - bot)
> > 
> >     def take(self):
> >         while 1:
> >             give = random.randrange(self.bot, self.over_top) 
> >             if not self.taken[give - self.bot]:
> >                 self.taken[give - self.bot] = 1
> >                 return give
> > 
> > if __name__ == '__main__':
> >     hat = NumberHat(0,10)
> >     for i in range(10):
> >         print hat.take()
> >             
> > ############################################################
> > # OUTPUT:
> > # bash-2.05a$ ./numberhat.py
> > # 1
> > # 5
> > # 6
> > # 9
> > # 3
> > # 7
> > # 0
> > # 8
> > # 2
> > # 4
> > # bash-2.05a$ 
> > 
> > ---
> > 
> > But there's no generator in it.  Is this natural?  Or is there
> > some other thought I should be thinking?
> > 
> > Thank you again and again.
> > 
> > Marilyn
> > 
> > 
> > _______________________________________________
> > Tutor maillist  -  Tutor at python.org
> > http://mail.python.org/mailman/listinfo/tutor
> > 
> 
> 

-- 




More information about the Tutor mailing list