# [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?

i searched c.l.p and found a thread that had the following:

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

```