Python Random choices() Method

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

ParameterConditionDescription
populationRequiredA sequence from which a random item is to be selected. It can be a list, tuple, string, range, or any sequence type.
weightsOptionalA list of numbers representing the probability of each element being chosen.
Default is None.
cum_weightsOptionalsame as weights, but this time the probability is accumulated.
Default is None.
kOptionalAn 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.