Two ideas (allow me to illustrate it with separated options and ratios for the sake of clarity in the argument names, if they're packed in a tuple you can save the "zip"):
a) Denormalize the weights to get integer ratios, then put in a list as many copies as the ratio and use random.choice
.
def choice_with_ratios(options, ratios):
tmp = sum([[v]*n for v, n in zip(options, ratios)], [])
return random.choice(tmp)
b) Use the normalized weights and start summing up until you reach a random generated uniform value
def choice_with_weights(options, weights):
s = 0
r = random.random()
for v, w in zip(options, weights):
s += w
if s >= r: break
return v
By the way, if the first field is used as a key, you should have it in a dictionary, like:
d = {
701: ((1, 0.2), (2, 0.3), (3, 0.5),
702: ((1, 0.3), (2, 0.2), (3, 0.5)
}