Usage
The random.choices()
method returns a list containing a randomly selected element from the specified sequence. The sequence can be a list, tuple, string, range, or any sequence type.
By using the weights
or cum_weights
parameters, you can control the probability of each element being chosen.
Syntax
random.choices(population, weights=None, *, cum_weights=None, k=1)
Parameters
Parameter | Condition | Description |
population | Required | A sequence from which a random item is to be selected. It can be a list, tuple, string, range, or any sequence type. |
weights | Optional | A list of numbers representing the probability of each element being chosen. Default is None. |
cum_weights | Optional | same as weights, but this time the probability is accumulated. Default is None. |
k | Optional | An integer defining the length of the returned list. Default is 1. |
Note that the *
is not a parameter. Rather, it indicates the end of the positional arguments. Every argument following the *
must be specified as a keyword argument.
Module Import
To use random.choices()
, you’ll first need to import the random module.
import random
Basic Example
The basic way to use random.choices()
is by providing the sequence you want to choose from and the number of elements to select.
import random
fruits = ['apple', 'banana', 'cherry', 'date']
print(random.choices(fruits, k=2))
# Might return ['apple', 'date']
Here, we’re asking Python to pick two fruits at random from the list fruits
. Since we haven’t provided any weights, each fruit has an equal chance of being picked. This is a simple random sampling, much like reaching into a bag of fruits and pulling out two without looking. You could get two different fruits or the same fruit twice.
Using Weights
Let’s understand how the weights
parameter in random.choices()
influences your random selections.
Imagine you have a bag filled with 10 apples, 1 banana, 1 cherry, and 1 date. If you reach in and randomly select a fruit with your eyes closed, you’re 10 times more likely to pull out an apple than the other fruits.
The weights
parameter in random.choices()
works similarly. When you provide a list of weights, you’re essentially controlling the probability of each item being selected. In this example:
import random
fruits = ['apple', 'banana', 'cherry', 'date']
weights = [10, 1, 1, 1]
print(random.choices(fruits, weights=weights, k=2))
# Might return ['apple', 'apple']
…the apple has a weight of 10, while the other fruits have a weight of 1. This means there’s a much higher chance of selecting “apple” when compared to the others.
Keep in mind that the weights
list must be the same length as your population
(the list of items you’re choosing from). If they don’t match, you’ll get a ValueError
.
fruits = ['apple', 'banana', 'cherry', 'date']
weights = [10, 1, 1]
print(random.choices(fruits, weights=weights, k=2))
# ValueError: The number of weights does not match the population
Also, if you set all the weights in the weights
list to zero, you’ll also get a ValueError
because there wouldn’t be any valid items to select.
Using Cumulative Weights
Cumulative weights are a different way to specify the same weighting concept. Instead of giving individual weights to items, you give the running total.
For example, if you have the weights [10, 1, 1, 1]
, the corresponding cumulative weights would be [10, 11, 12, 13]
.
fruits = ['apple', 'banana', 'cherry', 'date']
cum_weights = [10, 11, 12, 13]
print(random.choices(fruits, cum_weights=cum_weights, k=2))
# Might return ['apple', 'cherry']
Here’s how to understand it:
- Apple has a weight of 10 (as before).
- Banana has a weight of 1, so the total weight so far is 10 (apple) + 1 (banana) = 11.
- Cherry has a weight of 1, so the total weight now is 11 (previous total) + 1 (cherry) = 12.
- Date has a weight of 1, making the final total weight 13.
The process is still the same: an apple is 10 times more likely to be chosen than a banana, cherry, or date. By using cumulative weights, we’re essentially telling Python the upper boundary of each item in a continuous scale.
Weights vs Cumulative Weights
Both weights and cumulative weights convey the same idea of influencing the probability of selecting items. While the former directly assigns a weight to each item, the latter represents the running totals of those weights.
When using the random.choices()
method, it’s important to provide only one of weights
or cum_weights
; Specifying both would result in a TypeError
.
If neither weights
nor cum_weights
are specified, the selections are made with equal probability.
FYI, when you provide relative weights, the random.choices()
method internally converts them to cumulative weights for the selection process. By directly supplying cumulative weights, you can make the selection process slightly more efficient.