Elección, muestra y opciones para seleccionar aleatoriamente elementos de una lista en Python.

Negocio

Las funciones choice(), sample() y choices() del módulo random de la biblioteca estándar de Python pueden utilizarse para seleccionar y recuperar aleatoriamente elementos de una lista, tupla, cadena u otro objeto de secuencia (muestreo aleatorio).

choice() obtiene un único elemento, sample() y choices() obtienen una lista de múltiples elementos. sample() es una extracción no recuperable sin duplicados, choices() es una extracción recuperable con duplicados.

La siguiente información se proporciona aquí.

  • Selecciona un elemento al azar.: random.choice()
  • Seleccionar aleatoriamente varios elementos (sin duplicados): random.sample()
  • Seleccionar aleatoriamente varios elementos (con duplicados): random.choices()
  • Fijar la semilla de números aleatorios

Selecciona un elemento al azar.: random.choice()

Con la función choose() del módulo random, se selecciona al azar un elemento de la lista y se puede recuperar.

import random

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

print(random.choice(l))
# 1

Lo mismo ocurre con las tuplas y las cadenas. En el caso de las cadenas, se selecciona un solo carácter.

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

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

Error si se especifica una lista, tupla o cadena vacía como argumento.

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

Seleccionar aleatoriamente varios elementos (sin duplicados): random.sample()

Con la función sample() del módulo random, se pueden obtener múltiples elementos al azar de una lista. No hay duplicación de elementos (extracción no recuperable).

El primer argumento es una lista, y el segundo es el número de elementos a recuperar. Se devuelve la lista.

import random

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

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

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

Si el segundo argumento es 1, también se devuelve una lista con un elemento; si es 0, la lista está vacía. Si el segundo argumento es 1, se devuelve una lista con un elemento; si es 0, se devuelve una lista vacía; si el primer argumento es mayor que el número de elementos de la lista, se produce un error.

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

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

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

Si el primer argumento es una tupla o una cadena, lo que se devuelve sigue siendo una lista.

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

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

Si quieres volver a una tupla o cadena, utiliza tuple(),join().

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

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

Tenga en cuenta que el valor no se juzga, por lo que si la lista o tupla original contiene elementos con el mismo valor, existe la posibilidad de que se seleccione el mismo valor.

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

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

Si quiere evitar los valores duplicados, puede utilizar set() para convertirlo en un conjunto (tipo set) y extraer sólo los elementos únicos, y luego utilizar sample().

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

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

Seleccionar aleatoriamente varios elementos (con duplicados): random.choices()

La función choices() del módulo random permite recuperar múltiples elementos al azar de una lista, y a diferencia de sample(), permite seleccionar elementos duplicados.

choices() es una función añadida en Python 3.6. No está disponible en versiones anteriores.

El argumento k especifica el número de elementos a recuperar. Se permite la duplicación, por lo que el número de elementos a recuperar puede ser mayor que el número de elementos de la lista original.

Como k es un argumento de palabra clave, es necesario especificar una palabra clave, como 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]

El valor por defecto de k es 1; si se omite, se devuelve una lista con 1 elemento.

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

El argumento pesos puede utilizarse para especificar el peso (probabilidad) de que cada elemento sea seleccionado, y el tipo de los elementos de la lista puede ser int o 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]

El argumento cum_weights también puede especificarse como un peso acumulativo. El cum_weights en el siguiente código de ejemplo es equivalente a los primeros pesos anteriores.

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

El valor por defecto de los argumentos pesos y pesos_cum es None, lo que significa que cada elemento se selecciona con la misma probabilidad.

Si la longitud (número de elementos) del argumento pesos o cum_pesos es diferente de la lista original, se produce un error.

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

También es un error especificar pesos y cum_weights al mismo tiempo.

# 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

Hemos especificado una lista como primer argumento como ejemplo en el código de muestra hasta ahora, pero lo mismo se aplica a tuplas y cadenas.

Fijar la semilla de números aleatorios

Dando un número entero arbitrario a la función seed() del módulo random, la semilla de números aleatorios puede ser fijada y el generador de números aleatorios puede ser inicializado.

Tras la inicialización con la misma semilla, los elementos se seleccionan siempre de la misma manera.

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

random.seed(0)
print(random.choice(l))
# 3
Copied title and URL