[Tutor] generators and classes

Lloyd Kvam pythontutor at venix.com
Tue Feb 24 00:43:30 EST 2004


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.

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
> 

-- 
Lloyd Kvam
Venix Corp.
1 Court Street, Suite 378
Lebanon, NH 03766-1358

voice:	603-653-8139
fax:	801-459-9582




More information about the Tutor mailing list