Explanatory code for making weighted random choices.

Example: selecting from a jar with 2 red, 3 green, and 4 blue marbles.

Using an explicit list

```
import random
marbles = ['R'] * 2 + ['G'] * 3 + ['B'] * 4
print(random.choice(marbles))
```

What if we only know percentages? e.g. 37.524367% red, 23.96853% green, and 61.502897% blue

```
marbles = ['R'] * 37524367 + ['G'] * 23968530 + ['B'] * 61502897
print('marbles has a length of {}!'.format(len(marbles)))
```

If you are running Python 3.6, use the new method `random.choices()`

.

```
marbles = ['R', 'G', 'B']
weights = [37.524367, 23.96853, 61.502897]
print(random.choices(marbles, weights))
```

Or use a dictionary where keys are weighted by their values rather than having items and their weights in separate lists

```
m = {'R': 2, 'G': 3, 'B': 4}
m2 = {'R': .37524367, 'G': .23968530, 'B': .61502897}
```

`.keys()`

and `.values()`

are returned in congruent order

`print(random.choices(list(m2.keys()), (m2.values())))`

Pre Python 3.6, code your own weighted choice
Weighted random choice made by a series of `if`

-`elif`

statements

```
x = random.randint(1, 9)
print(x)
if 0 < x <= m['R']:
print('R')
elif m['R'] < x <= m['R'] + m['G']:
print('G')
elif m['R'] + m['G'] < x <= m['R'] + m['G'] + m['B']:
print('B')
else:
print('Problem!')
```

Use a loop instead

```
x = random.randint(1, sum(m.values()))
print(x)
cum_weight = 0
for key in m:
if cum_weight < x <= m[key] + cum_weight:
print(key)
break
cum_weight += m[key]
else:
print('Problem')
```

Use a function instead

`def weighted_choice(weights):`

for non-integer sum of weights
`ValueError: non-integer stop for randrange()`

```
x = random.randint(1, sum(weights.values()))
cum_weight = 0
for key in weights:
if cum_weight < x <= weights[key] + cum_weight:
return key
cum_weight += weights[key]
return 'Problem!'
```

But what about non-integer weights?

```
def weighted_choice(weights):
x = random.random() * sum(weights.values())
cum_weight = 0
for key in weights:
if cum_weight <= x <= weights[key] + cum_weight:
return key
cum_weight += weights[key]
return 'Problem!'
```