Choice, sample, and choices to randomly select elements from a list in Python.

Money and Business

The functions choice(), sample(), and choices() in the random module of the Python standard library can be used to randomly select and retrieve elements from a list, tuple, string, or other sequence object (random sampling).

choice() gets a single element, sample() and choices() get a list of multiple elements. sample() is non-recoverable extraction with no duplicates, choices() is recoverable extraction with duplicates.

The following information is provided here.

  • Select one element at random.: random.choice()
  • Randomly select multiple elements (no duplicates): random.sample()
  • Randomly select multiple elements (with duplicates): random.choices()
  • Fix the random number seed

Select one element at random.: random.choice()

With the random module's function choose(), one element is randomly selected from the list and can be retrieved.

import random

l = [0, 1, 2, 3, 4]

print(random.choice(l))
# 1

The same applies to tuples and strings. In the case of strings, a single character is selected.

print(random.choice(('xxx', 'yyy', 'zzz')))
# yyy

print(random.choice('abcde'))
# b

Error if an empty list, tuple, or string is specified as an argument.

# print(random.choice([]))
# IndexError: Cannot choose from an empty sequence

Randomly select multiple elements (no duplicates): random.sample()

With the function sample() of the random module, you can get multiple elements at random from a list. There is no duplication of elements (non-recoverable extraction).

The first argument is a list, and the second argument is the number of elements to be retrieved. The list is returned.

import random

l = [0, 1, 2, 3, 4]

print(random.sample(l, 3))
# [2, 4, 0]

print(type(random.sample(l, 3)))
# <class 'list'>

If the second argument is set to 1, a list with one element is also returned; if it is set to 0, the list is empty. If the second argument is 1, a list with one element is returned; if it is 0, an empty list is returned; if the first argument is more than the number of elements in the list, an error occurs.

print(random.sample(l, 1))
# [3]

print(random.sample(l, 0))
# []

# print(random.sample(l, 10))
# ValueError: Sample larger than population or is negative

If the first argument is a tuple or a string, what is returned is still a list.

print(random.sample(('xxx', 'yyy', 'zzz'), 2))
# ['xxx', 'yyy']

print(random.sample('abcde', 2))
# ['b', 'e']

If you want to return to a tuple or string, use tuple(),join().

print(tuple(random.sample(('xxx', 'yyy', 'zzz'), 2)))
# ('xxx', 'yyy')

print(''.join(random.sample('abcde', 2)))
# dc

Note that the value is not judged, so if the original list or tuple contains elements with the same value, there is a possibility that the same value will be selected.

l_dup = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]

print(random.sample(l_dup, 3))
# [3, 1, 1]

If you want to avoid duplicate values, you can use set() to convert it to a set (set type) and extract only the unique elements, and then use sample().

print(set(l_dup))
# {0, 1, 2, 3}

print(random.sample(set(l_dup), 3))
# [1, 3, 2]

Randomly select multiple elements (with duplicates): random.choices()

The random module's function choices() allows you to retrieve multiple elements at random from a list, and unlike sample(), it allows duplicate elements to be selected.

choices() is a function added in Python 3.6. It is not available in earlier versions.

The argument k specifies the number of elements to be retrieved. Duplication is allowed, so the number of elements to be retrieved can be larger than the number of elements in the original list.

Since k is a keyword-only argument, it is necessary to specify a keyword, such as k=3.

import random

l = [0, 1, 2, 3, 4]

print(random.choices(l, k=3))
# [2, 1, 0]

print(random.choices(l, k=10))
# [3, 4, 1, 4, 4, 2, 0, 4, 2, 0]

The default value of k is 1; if it is omitted, a list with 1 element is returned.

print(random.choices(l))
# [1]

The argument weights can be used to specify the weight (probability) that each element will be selected, and the type of the elements in the list can be int or float.

print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1]))
# [0, 2, 3]

print(random.choices(l, k=3, weights=[1, 1, 0, 0, 0]))
# [0, 1, 1]

The argument cum_weights can also be specified as a cumulative weight. The cum_weights in the following sample code is equivalent to the first weights above.

print(random.choices(l, k=3, cum_weights=[1, 2, 3, 13, 14]))
# [3, 2, 3]

The default for both arguments weights and cum_weights is None, which means that each element is selected with the same probability.

If the length (number of elements) of the argument weights or cum_weights is different from the original list, an error occurs.

# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1, 1, 1]))
# ValueError: The number of weights does not match the population_

It is also an error to specify weights and cum_weights at the same time.

# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1], cum_weights=[1, 2, 3, 13, 14]))
# TypeError: Cannot specify both weights and cumulative weights

We have specified a list as the first argument as an example in the sample code so far, but the same applies to tuples and strings.

Fix the random number seed

By giving an arbitrary integer to the random module's function seed(), the random number seed can be fixed and the random number generator can be initialized.

After initialization with the same seed, the elements are always selected in the same way.

random.seed(0)
print(random.choice(l))
# 3

random.seed(0)
print(random.choice(l))
# 3