[EMAIL PROTECTED] wrote: > But i am stuck on how to do a random chooser that works according to my > idea of choosing according to rating system. It seems to me to be a bit > different that just choosing a weighted choice like so:
... > And i am not sure i want to have to go through what will be hundreds of > sound files and scale their ratings by hand so that they all add up to > 100%. I just want to have a long list that i can add too whenever i > want, and assign it a grade/rating according to my whims! Indeed, manually normalizing all those weights would be a downright sinful waste of time and effort. The solution (to any problem, really) starts with how you conceptualize it. For this problem, consider the interval [0, T), where T is the sum of all the weights. This interval is made up of adjacent subintervals, one for each weight. Now pick a random point in [0, T). Determine which subinterval this point is in, and you're done. import random def choose_weighted(zlist): point = random.uniform(0, sum(weight for key, weight in zlist)) for key, weight in zlist: # which subinterval is point in? point -= weight if point < 0: return key return None # will only happen if sum of weights <= 0 You'll get bogus results if you use negative weights, but that should be obvious. Also note that by using random.uniform instead of random.randrange, floating point weights are handled correctly. Test it: >>> data = (('foo', 1), ('bar', 2), ('skipme', 0), ('baz', 10)) >>> counts = dict((key, 0) for key, weight in data) >>> for i in range(10000): ... counts[choose_weighted(data)] += 1 ... >>> [(key, counts[key]) for key, weight in data] [('foo', 749), ('bar', 1513), ('skipme', 0), ('baz', 7738)] >>> --Ben -- http://mail.python.org/mailman/listinfo/python-list