La aleatoriedad nos rodea. Por ejemplo, cuando lanzas una moneda, o un dado, nunca se puede estar seguro del resultado final. Esta imprevisibilidad cuenta con muchas aplicaciones, como la de determinar los ganadores de un sorteo, o generar casos de prueba para un experimento con valores aleatorios generados por un algoritmo.
Con esta utilidad en mente, Python nos proporciona el módulo random. Puedes utilizarlo en juegos para generar enemigos al azar, o para mezclar los elementos de una lista...
¿Cómo funciona random?
Casi todas las funciones de este módulo dependen de la función random() básica, que produce un float aleatorio mayor o igual a cero y menor que uno. Python utiliza el Mersenne Twister para generar los floats, los cuales cuentan con una precisión de 53 bits con un periodo de 2**19937-1. En realidad es el generador de números más ampliamente utilizado.
Es posible que a veces necesites reproducir la misma secuencia de números que generaste la primera vez. Esto puede lograrse proporcionándole a la función el mismo parámetro seed (s). Si se omite el parámetros s, el generador usará la hora actual del sistema para generar los números. Aquà tienes un ejemplo:
import random random.seed(100) random.random() # returns 0.1456692551041303 random.random() # returns 0.45492700451402135
Ten en cuenta que, a diferencia del lanzamiento de una moneda, el módulo genera pseudo-números aleatorios que son completamente deterministas, por lo que no son adecuados para términos criptográficos.
Generación de números enteros aleatorios
El módulo cuenta con dos funciones distintas para generar números enteros aleatororios. Puedes utilizar randarange(a) para generar un numero aleatorio menos que a.
Del mismo modo, puedes utilizar randrange (a, b [, step]) para generar un número aleatorio desde el rango (a, b, step). Por ejemplo, usando random.randrange(0, 100, 3) sólo devolverá aquellos números entre 0 y 100 que también sean divisibles entre 3.
Si conoces tanto el lÃmite superior como el inferior entre los que desea generar los números, puedes utilizar una función más simple e intuitiva llamada randint(a, b). Es simplemente un alias de randrange(a, b + 1).
import random random.randrange(100) # returns 65 random.randrange(100) # returns 98 random.randrange(0, 100, 3) # returns 33 random.randrange(0, 100, 3) # returns 75 random.randint(1,6) # returns 4 random.randint(1,6) # returns 6
Funciones para secuencias
Para seleccionar un elemento aleatorio de una secuencia no vacÃa dada, puedes utilizar la función choice(seq). Con randint(), estás limitado a una selección de números dentro de un rango dado. La función choice(seq) te permite elegir un número de cualquier secuencia que desees.
Otra cosa muy buena de esta función es que no se limita a sólo números. Puedes seleccionar cualquier tipo de elemento de forma aleatoria de una secuencia. Por ejemplo, el nombre del ganador de un sorteo entre cinco personas diferentes, proporcionado como una string, se puede determinar utilizando esta función de forma sencilla.
Si desea mezclar una secuencia en lugar de seleccionar un elemento aleatorio de ella, puedes utilizar la función shuffle(seq). Esto generará la secuencia mezclada de forma aleatoria. Para una secuencia con sólo 10(n) elementos, puede haber un total de 3628800 (n!) permutaciones distintas. Con una secuencia mayor, el número de permutaciones posibles será aún mayor, lo que implica que la función nunca podrá generar todas las permutaciones de una secuencia grande.
Digamos que tienes que elegir 50 estudiantes de un grupo de 100 estudiantes para ir de viaje.
En este punto, puedes estar tentado a utilizar la función de choice(seq). El problema es que tendrás que llamarla sobre las 50 veces, siempre en el mejor de los casos, ya que puede pasar que algún personaje salga repetido.
Lo mejor es utilizar la función de sample(seq, k). Devolverá una lista de k elementos únicos de la secuencia dada. La secuencia original no se modifica. Los elementos de la lista resultante estarán en orden de selección. Si k es mayor que el número de elementos de la secuencia misma, se devolverá un ValueError.
import random ids = [1, 8, 10, 12, 15, 17, 25] random.choice(ids) # returns 8 random.choice(ids) # returns 15 names = ['Tom', 'Harry', 'Andrew', 'Robert'] random.choice(names) # returns Tom random.choice(names) # returns Robert random.shuffle(names) names # returns ['Robert', 'Andrew', 'Tom', 'Harry'] random.sample(names, 2) # returns ['Andrew', 'Robert'] random.sample(names, 2) # returns ['Tom', 'Robert'] names # returns ['Robert', 'Andrew', 'Tom', 'Harry']
Generación de números floats aleatorios
En esta sección, veremos funciones que se pueden utilizar para generar números aleatorios basándose en distribuciones especÃficas de valores reales. Los parámetros de la mayorÃa de estas funciones tienen el nombre de la variable correspondiente en la ecuación real de la distribución.
Cuando sólo desees un número entre 0 y 1, puede utilizar la función random(). Si deseas que el número esté en un rango especÃfico, puede usar la función uniform(a, b) siendo a y b los lÃmites inferior y superior, respectivamente.
Digamos que necesitas generar un número aleatorio entre bajo y alto. Puedes hacerlo con la función triangular(bajo, alto, modo). Los valores bajos y altos serán 0 y 1 por defecto. Del mismo modo, el valor de modo predeterminado es el punto medio del valor bajo y alto, resultando en una distribución simétrica.
Existen otras muchas funciones para generar números aleatorios basadas en diferentes distribuciones. A modo de ejemplo, puedes utilizar normalvariate(mu, sigma) para generar un número aleatorio basándose en una distribución normal, con mu como media y sigma como desviación estándar.
import random random.random() # returns 0.8053547502449923 random.random() # returns 0.05966180559620815 random.uniform(1, 20) # returns 11.970525425108205 random.uniform(1, 20) # returns 7.731292430291898 random.triangular(1, 100, 80) # returns 42.328674062298816 random.triangular(1, 100, 80) # returns 73.54693076132074
Fuente: Monty Shokeen