[Tutor] (No Subject)

kevin parks kp87@lycos.com
Fri, 22 Feb 2002 01:59:32 +0900

```I am trying to add  weights or probabilities to a list of items to be chosen
randomly from a list.

A straight-ahead random picker would be something like:
>>> import random
>>> x=['one', 'two', 'three']
>>> item = random.choose(x)
'two'

here all items have an equal (33.3333% chance) of being picked.

Now i want to say that 'one' has a 10% chance of being picked,
'two' a 30% chance, and 'three' 60% or whatever...

The poor person's way of doing this is to stack the deck:
x=['one', 'two', 'two', 'two', 'three', 'three', 'three', 'three', 'three', 'three']

But i would rather specify with more flexibility like so:

list1=[('one', 0.10), ('two', 0.30), ('three', 0.60)]
-or-
list1=[[one', 0.10], ['two', 0.30], ['three', 0.60]]

and fancier things..

so i am starting with something like this (I am at a PC room with no
interpreter so if i make a type forgive me)... my version...

import random

def wc(lst):
n = random.uniform(0,1)
for item, weight in lst:
if n < weight:
break
n = n - weight
return item

###

was i headed down the right path here?

someone said that the subtraction is not
needed and the comparison with 1.0 can then be eliminated.  By putting largest
weights first, the remaining number of comparisons is minimized:

list1 = [('three', 0.5), ('two', 0.75)] # else 'one'
def wc(list):
n = random.uniform(0, 1)
for item, weight in list:
if n < weight:
return item
return 'one'

I don't understand this since then our last choice has to be hardwired in that
second return statement. I am guessing that the 0.75 is a type and was supposed
to be a 0.25

someone else suggested this with the disclaimer that it
was not very efficient method and was untested:

def weighted_choice(choices):
tot = 0
for w,v in choices:
tot = tot + w
d = random.random()*tot
tot = 0
for w,v in choices:
tot = tot + w
if tot > d:
return v

I am not yet able to get my head around this one but i put it through danny's histogram()
and it seemed to work.  Which approach is more better (more robust, faster, all-purpose,
efficient, etc.)

Check out Cupid School where you will learn from Matchmaker's
best and brightest. Good Luck!

http://ecard.matchmaker.com/cupid0202/cupid0202.html

```