Advertisement
  1. Code
  2. Python

Módulos Matemáticos en Python: Random

Scroll to top
Read Time: 7 min
This post is part of a series called Mathematical Modules in Python.
Mathematical Modules in Python: Math and Cmath
Mathematical Modules in Python: Decimal and Fractions

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

La aleatoriedad está en todas partes. Cuando lanzas una moneda o un dado, nunca puedes estar seguro del resultado final. Esta impredecibilidad tiene muchas aplicaciones como determinar los ganadores de un sorteo o generar casos de prueba para un experimento con valores aleatorios producidos basados en un algoritmo.

Manteniendo esta utilidad en mente, Python nos ha proporcionado el módulo random. Puedes usarlo en juegos para engendrar enemigos de manera aleatoria o barajar los elementos en una lista.

¿Cómo Funciona Random?

Casi todas las conclusiones en este módulo dependen de la función básica random(), la cuál generará un flotante aleatorio mayor o igual a cero y menos que uno. Python usa el Mersenne Twister para generar los flotantes. Este produce flotantes con precisión de 53 bits con un periodo de 2**19937-1. Es de hecho el generador de números pseudo aleatorios de propósito general usado más ampliamente.

Algunas veces, quieres que el generador de números aleatorios reproduzca la secuencia de números que creó la primera vez. Esto puede ser logrado proporcionando el mismo valor semilla ambas veces para el generador usando la función seed(s, version). Si el parámetro s es omitido, el generador usará la hora actual del sistema para generar los números. Aquí está un ejemplo:

1
import random
2
3
random.seed(100)
4
5
random.random() 
6
# returns 0.1456692551041303

7
8
random.random()
9
# returns 0.45492700451402135

Ten en mente que a diferencia de lanzar una monda, el módulo genera números pseudo aleatorios que son completamente determinantes, así que no es adecuado para propósitos criptográficos.

Generando Enteros Aleatorios

El módulo tiene dos funciones diferentes para generar enteros aleatorios. Puedes usar randrange(a) para generar un número entero aleatorio menor que a.

De manera similar, puedes usar randrange(a, b[,step]) para generar un número aleatorio desde range(a, b, step). Por ejemplo, usar random.randrange(0, 100, 3) solo devolverá aquellos números entre 0 y 100 que también sean divisibles por 3.

Si quieres saber tanto el límite inferior como superior entre el cuál quieres generar los números, puedes usar una función más simple e intuitiva llamada randint(a, b). Es simplemente un alias para randrange(a, b+1).

1
import random
2
3
random.randrange(100)
4
# returns 65

5
6
random.randrange(100)
7
# returns 98

8
9
random.randrange(0, 100, 3)
10
# returns 33

11
12
random.randrange(0, 100, 3)
13
# returns 75

14
15
random.randint(1,6)
16
# returns 4

17
18
random.randint(1,6)
19
# returns 6

Funciones para Secuencias

Para seleccionar un elemento aleatorio de una secuencia no vacía dada, puedes usar la función choice(seq). Con randint(), estás limitado a una selección de números de un rango dado. La función choice(seq) te permite elegir un número de cualquier secuencia que quieras.

Otra cosa buena sobre esta función es que no está limitada a solo números. Puede seleccionar cualquier tipo de elemento de manera aleatoria desde una secuencia. Por ejemplo, el nombre del ganador de un sorteo entre cinco personas diferentes, proporcionado como cadena, puede ser determinado usando esta función fácilmente.

Si quieres barajar una secuencia en vez de seleccionar un elemento aleatorio de esta, puedes usar la función shuffle(seq). Esto resultará en un barajeo en lugar de la secuencia. Para una secuencia con solo 10(n) elementos, puede haber un total de 3628800(n!) arreglos diferentes. Con una secuencia más grande, el número de posibles permutaciones será incluso mayor--esto implica que la función nunca puede generar todas las permutaciones de una secuencia grande.

Digamos que tienes que elegir 50 estudiantes de un grupo de 100 estudiantes para ir a un viaje.

En este punto, podrías estar tentado a usar la función choice(seq). El problema es que tendrás que llamarla cerca de 50 veces en el mejor de los casos en donde no elige al mismo estudiante de nuevo.

Una mejor solución es usar la función sample(seq, k). Esta devolverá una lista de k elementos únicos de la secuencia dada. La secuencia original permanece sin cambios.                      Los elementos en la lista resultante estarán en orden de selección. Si k es mayor que el número de elementos en la secuencia misma, un ValueError será generado.

1
import random
2
3
ids = [1, 8, 10, 12, 15, 17, 25]
4
5
random.choice(ids)           # returns 8

6
random.choice(ids)           # returns 15

7
8
names = ['Tom', 'Harry', 'Andrew', 'Robert']
9
10
random.choice(names)         # returns Tom

11
random.choice(names)         # returns Robert

12
13
random.shuffle(names)
14
names                        
15
# returns ['Robert', 'Andrew', 'Tom', 'Harry']

16
17
random.sample(names, 2)
18
# returns ['Andrew', 'Robert']

19
20
random.sample(names, 2)
21
# returns ['Tom', 'Robert']

22
23
names
24
# returns ['Robert', 'Andrew', 'Tom', 'Harry']

25

Como puedes ver, shuffle(seq) modificó la lista original, pero sample(seq, k) la mantuvo intacta.

Generando Flotantes Aleatorios

En esta sección, aprenderás sobre funciones que pueden ser usadas para generar número aleatorios basados sobre distribuciones de valor real específicas. Los parámetros de la mayoría de estas funciones son nombradas por su variable correspondiente en la ecuación actual de esa distribución.

Cuando solo quieres un número entre 0 y 1, puedes usar la función random(). Si quieres el número en un rango específico, puedes usar la función uniform(a, b) con a y b como los límites más bajo y alto respectivamente.

Digamos que necesitas generar un número aleatorio entre bajo y alto de tal manera que tenga una probabilidad más alta de caer en el vacío de otro modo de número. Puedes hacer esto con la función triangular(low, high, mode). Los valores low y high serán 0 y 1 por defecto. De manera similar, el valor mode está al punto medio del valor bajo y alto, resultando en una distribución simétrica.

Hay muchas otras funciones también para generar números aleatorios basado en distribuciones diferentes. Como ejemplo, puedes usar normalvariate(mu, sigma) para generar un número aleatorio basado en una distribución normal, con mu como media y sigma como desviación estándar.

1
import random
2
3
random.random()
4
# returns 0.8053547502449923

5
6
random.random()
7
# returns 0.05966180559620815

8
9
random.uniform(1, 20)
10
# returns 11.970525425108205

11
12
random.uniform(1, 20)
13
# returns 7.731292430291898

14
15
random.triangular(1, 100, 80)
16
# returns 42.328674062298816

17
18
random.triangular(1, 100, 80)
19
# returns 73.54693076132074

20

Probabilidades Ponderadas

Como acabamos de ver, es posible generar números aleatorios con distribución uniforme así como distribución triangular o normal. Incluso en un rango finito como 0 a 100, hay un número infinito de flotantes que pueden ser generados. ¿Qué pasa si hay un conjunto finito de elementos y quieres agregar más ponderación a algunos valores específicos cuando seleccionas un número aleatorio? Esta situación es común en sistemas de lotería en donde los números con mejor recompensa tienen una mayor ponderación.

Si es aceptable para tu aplicación tener ponderaciones que sean valores enteros, puedes crear una lista de elementos cuya frecuencia dependa de tu ponderación. Puedes usar entonces la función choice(seq) para seleccionar un elemento de esta lista ponderada aleatoriamente. Aquí está un ejemplo mostrando la selección de la cantidad de un premio de manera aleatoria.

1
import random
2
3
w_prizes = [('$1', 300), ('$2', 50), ('$10', 5), ('$100', 1)]
4
prize_list = [prize for prize, weight in w_prizes for i in range(weight)]
5
6
random.choice(prize_list)
7
# returns '$1'

En mi caso, tomó diez intentos obtener un premio de $2 elegido de la lista. Las posibilidades de obtener un premio de $100 serían mucho más bajas. De manera similar, también puedes agregar parcialidad a otros programas.

Ideas Finales

Este módulo puede ser útil en muchas situaciones como barajar las preguntas en una tarea o generar nombres de usuario o contraseñas aleatorias para tus usuarios usando la función shuffle(). También puedes generar número aleatorios de manera uniforme así como darle peso a números en un rango específico. En nuestro siguiente tutorial, estaremos usando las funciones de este módulo para generar información aleatoria para análisis estadístico.

¿Tienes algunas aplicaciones interesantes o generadores de números aleatorios en mente que puedan ser útiles para otros lectores? Déjanos saber en los comentarios.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.