def weighted_choice(choices):
values, weights = zip(*choices)<EOL>total = <NUM_LIT:0><EOL>cum_weights = []<EOL>for w in weights:<EOL><INDENT>total += w<EOL>cum_weights.append(total)<EOL><DEDENT>x = random.uniform(<NUM_LIT:0>, total)<EOL>i = bisect.bisect(cum_weights, x)<EOL>return values[i]<EOL>
Returns a value from choices chosen by weighted random selection

    choices should be a list of (value, weight) tuples.

    eg. weighted_choice([('val1', 5), ('val2', 0.3), ('val3', 1)])