Smarter way of doing this?

Max M maxm at mxm.dk
Tue Feb 3 08:54:14 CET 2004


Jim Jewett wrote:

> Max M <maxm at mxm.dk> wrote in message news:<401e4d57$0$295$edfadb0f at dread12.news.tele.dk>...
> 
> You may wish to look at the GRADES example in the bisect documentation.

First of, thanks for the replies!

I finally chose a combination of the suggested approaches, and ended up 
with something I find is both more functional and nicer to look at than 
my first try.

regards Max M


################################

from random import random
from bisect import bisect

class Selector:

     "Returns random elements by probability"

     def __init__(self, probabilities, elements):
         self.sum = sum(probabilities)
         self.decorated = zip(probabilities, elements)
         self.decorated.sort()

     def get(self):
         "Randomly returns an element by probability"
         rnd = random() * self.sum
         index = bisect(self.decorated, (rnd, 0))-1
         return self.decorated[index][-1]

     def get_range(self, n):
         "Randomly returns a range of elements by probability"
         return [self.get() for itm in range(n)]


if __name__ == '__main__':

     probabilities = []
     for f in range(0,10):
         probabilities.append(1.0 / (f+1.0))

     elements = ['a','b','c','d','e','f','g','h','i','j',]

     s = Selector(probabilities, elements)
     result = s.get_range(1000)
     result.sort()

     print result



More information about the Python-list mailing list