A weighted version of random.choice A weighted version of random.choice python python

# A weighted version of random.choice

Since version 1.7.0, NumPy has a `choice` function that supports probability distributions.

``from numpy.random import choicedraw = choice(list_of_candidates, number_of_items_to_pick,              p=probability_distribution)``

Note that `probability_distribution` is a sequence in the same order of `list_of_candidates`. You can also use the keyword `replace=False` to change the behavior so that drawn items are not replaced.

Since Python 3.6 there is a method `choices` from the `random` module.

``In : import randomIn : random.choices(...:     population=[['a','b'], ['b','a'], ['c','b']],...:     weights=[0.2, 0.2, 0.6],...:     k=10...: )Out:[['c', 'b'], ['c', 'b'], ['b', 'a'], ['c', 'b'], ['c', 'b'], ['b', 'a'], ['c', 'b'], ['b', 'a'], ['c', 'b'], ['c', 'b']]``

Note that `random.choices` will sample with replacement, per the docs:

Return a `k` sized list of elements chosen from the population with replacement.

If you need to sample without replacement, then as @ronan-paixão's brilliant answer states, you can use `numpy.choice`, whose `replace` argument controls such behaviour.
``def weighted_choice(choices):   total = sum(w for c, w in choices)   r = random.uniform(0, total)   upto = 0   for c, w in choices:      if upto + w >= r:         return c      upto += w   assert False, "Shouldn't get here"``