El módulo random es una de las bibliotecas estándar más versátiles de Python. Ya sea que necesites generar números aleatorios, elegir elementos de una lista, mezclar datos o crear simulaciones, random es la herramienta indicada. En esta guía completa aprenderás desde lo básico hasta técnicas avanzadas con ejemplos prácticos.
Generar datos aleatorios es esencial en múltiples áreas: desarrollo de videojuegos, pruebas de software, simulaciones científicas, muestreo estadístico, machine learning y mucho más. Python hace que este trabajo sea simple e intuitivo con su módulo random nativo.
Si estás comenzando, echa un vistazo a nuestra guía completa para principiantes en Python antes de sumergirte en este artículo.
¿Por Qué Usar el Módulo Random?
El módulo random implementa generadores de números pseudoaleatorios para varias distribuciones. Aunque los números parecen aleatorios, se generan mediante un algoritmo determinista. Para aplicaciones que requieren aleatoriedad criptográfica, Python ofrece el módulo secrets.
Los casos de uso principales incluyen:
- Videojuegos: generar posiciones, atributos, botines y comportamientos impredecibles
- Pruebas: crear datos de prueba variados y representativos
- Simulaciones: modelar fenómenos aleatorios como colas, tráfico y finanzas
- Muestreo: seleccionar subconjuntos representativos de poblaciones
- Machine Learning: mezclar datos, inicializar pesos y crear divisiones entrenamiento/prueba
Otra función útil es random.getrandbits(k), que devuelve un entero con k bits aleatorios. Es eficiente para generar números grandes sin necesidad de especificar intervalos manualmente.
import random
Número de 8 bits (0 a 255)
print(random.getrandbits(8)) # Ejemplo: 187
Número de 16 bits (0 a 65535)
print(random.getrandbits(16)) # Ejemplo: 42351
Con random, puedes simular escenarios complejos en pocas líneas de código. Veamos las principales funciones en la práctica.
Funciones Principales del Módulo Random
El módulo ofrece decenas de funciones. La documentación oficial de Python es la referencia completa, pero aquí cubriremos las más utilizadas en el día a día. Todas comparten el mismo generador subyacente, lo que permite mezclar llamadas de diferentes funciones sin problemas.
random.random() — Número Float Aleatorio
La función más básica: devuelve un número float aleatorio en el rango [0.0, 1.0).
import random
print(random.random()) # Ejemplo: 0.3746325874916233
print(random.random()) # Ejemplo: 0.8921567432810459
Útil para generar probabilidades, porcentajes o normalizar datos.
random.randint() — Entero Aleatorio
Devuelve un número entero aleatorio entre A y B (inclusive):
import random
dado = random.randint(1, 6)
print(f'Sacaste un {dado} en el dado')
loteria = random.randint(1, 60)
print(f'Número de lotería: {loteria}')
Esta es probablemente la función más popular del módulo. Usa randint siempre que necesites un valor entero dentro de un rango.
random.randrange() — Entero con Paso
Similar a randint, pero acepta un parámetro step opcional, igual que la función range():
import random
Número par aleatorio entre 0 y 20
par = random.randrange(0, 21, 2)
print(f'Número par: {par}')
Múltiplo de 5 entre 0 y 50
mult5 = random.randrange(0, 51, 5)
print(f'Múltiplo de 5: {mult5}')
Esta función es útil cuando necesitas números que sigan un patrón específico, como generar índices pares o valores en progresión aritmética.
random.uniform() — Float en Rango Personalizado
Similar a random(), pero permite definir los límites:
import random
temperatura = random.uniform(36.0, 40.0)
print(f'Temperatura simulada: {temperatura:.1f}°C')
precio = random.uniform(10.50, 99.90)
print(f'Precio aleatorio: ${precio:.2f}')
random.choice() — Seleccionar un Elemento Aleatorio
Elige un elemento aleatorio de una secuencia (lista, tupla, cadena):
import random
frutas = ['manzana', 'plátano', 'naranja', 'uva', 'fresa']
print(random.choice(frutas)) # Ejemplo: 'naranja'
Con cadenas
letra = random.choice('ABCDEFGH')
print(letra) # Ejemplo: 'C'
random.choice() se usa ampliamente en sorteos, juegos y pruebas A/B.
Para entender mejor cómo funcionan las listas en Python, consulta nuestra guía completa de manipulación de listas.
random.choices() — Múltiples Elementos con Reposición
Selecciona K elementos de una población, permitiendo repeticiones. Acepta pesos para definir probabilidades:
import random
colores = ['rojo', 'azul', 'verde']
pesos = [0.5, 0.3, 0.2] # 50% rojo, 30% azul, 20% verde
resultado = random.choices(colores, weights=pesos, k=10)
print(resultado)
Ejemplo: ['rojo', 'azul', 'rojo', 'verde', 'azul', ...]
Esta función es fantástica para simular distribuciones de probabilidad personalizadas.
random.sample() — Muestra sin Reposición
Selecciona K elementos únicos de una población, sin repetir:
import random
alumnos = ['Ana', 'Bruno', 'Carla', 'Daniel', 'Elena', 'Felipe']
seleccionados = random.sample(alumnos, 3)
print(f'Seleccionados: {seleccionados}')
Números de lotería
loteria = random.sample(range(1, 61), 6)
print(f'Lotería: {sorted(loteria)}')
Usa sample cuando cada elemento pueda ser elegido solo una vez, como en sorteos, divisiones de datos para machine learning y validación cruzada.
random.shuffle() — Mezclar una Lista
Mezcla los elementos de una lista in-place (modifica la lista original):
import random
cartas = ['A♠', 'K♠', 'Q♠', 'J♠', '10♠', '9♠', '8♠']
random.shuffle(cartas)
print(cartas) # Ejemplo: ['Q♠', 'A♠', '10♠', 'K♠', '9♠', 'J♠', '8♠']
Para datos de entrenamiento
datos = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
random.shuffle(datos)
entreno, prueba = datos[:7], datos[7:]
print(f'Entreno: {entreno}')
print(f'Prueba: {prueba}')
Mezclar datos es un paso crítico en el preprocesamiento de machine learning para evitar sesgos de orden.
Trabajar con Semillas (Seeds)
Los números pseudoaleatorios se generan a partir de una semilla (seed). Si usas la misma semilla, obtienes exactamente la misma secuencia. Esto es esencial para la reproducibilidad en experimentos científicos y machine learning.
import random
random.seed(42)
print(random.randint(1, 100)) # Siempre 82
print(random.random()) # Siempre 0.639426798...
random.seed(42) # Reiniciando la semilla
print(random.randint(1, 100)) # Otra vez 82
Según Real Python, usar semillas es una de las mejores prácticas en ciencia de datos, ya que garantiza que tus experimentos puedan ser reproducidos por otros investigadores.
Consejo Profesional: Capturar el Estado del Generador
Por defecto, Python siembra el generador desde os.urandom(), que utiliza fuentes verdaderamente aleatorias del sistema operativo. Puedes capturar el estado actual con random.getstate() y restaurarlo después. Esto es especialmente útil en depuración: puedes guardar el estado antes de una secuencia de operaciones, probar varias veces y siempre volver al mismo punto de partida.
import random
estado = random.getstate()
Genera tantos números como necesites...
random.setstate(estado) # Vuelve al estado anterior
Distribuciones Estadísticas
El módulo random proporciona funciones para varias distribuciones estadísticas, fundamentales para simulaciones científicas:
Distribución Uniforme
import random
Valores uniformemente distribuidos entre 0 y 10
for _ in range(5):
print(random.uniform(0, 10))
Distribución Normal (Gaussiana)
import random
Media 0, desviación estándar 1
for _ in range(5):
print(random.gauss(0, 1))
Altura simulada de una población
altura = random.gauss(170, 10) # Media 170cm, DE 10cm
print(f'Altura simulada: {altura:.1f} cm')
Distribución Triangular
La distribución triangular es útil cuando conoces el valor mínimo, el máximo y el valor más probable (moda) de un fenómeno:
import random
Simular tiempo de finalización de una tarea (optimista: 2h, probable: 4h, pesimista: 8h)
tiempo_estimado = random.triangular(2, 8, 4)
print(f'Tiempo estimado: {tiempo_estimado:.1f} horas')
Popular en simulaciones de gestión de proyectos (PERT)
duracion = random.triangular(10, 30, 15)
print(f'Duración simulada: {duracion:.1f} días')
Esta distribución se usa ampliamente en simulaciones de ingeniería y gestión de proyectos cuando los datos históricos son limitados.
Distribución Exponencial
import random
Simular tiempo entre llegadas en una cola
lambda_param = 2.0 # 2 llegadas por minuto
tiempo = random.expovariate(lambda_param)
print(f'Tiempo hasta próxima llegada: {tiempo:.2f} minutos')
Para un manejo más robusto de distribuciones, NumPy ofrece funciones optimizadas. Consulta el módulo numpy.random para aplicaciones científicas de alto rendimiento. Si quieres profundizar en NumPy, visita nuestra guía completa de NumPy.
Casos de Uso Reales
1. Simulador de Dados
import random
def lanzar_dado(lados=6):
return random.randint(1, lados)
Simular 1000 lanzamientos
resultados = [lanzardado() for in range(1000)]
frecuencias = {i: resultados.count(i) for i in range(1, 7)}
print(frecuencias)
2. Generador de Contraseñas Aleatorias
import random
import string
def generar_contraseña(longitud=12):
caracteres = string.asciiletters + string.digits + '!@#$%&*'
return ''.join(random.choice(caracteres) for in range(longitud))
print(generar_contraseña()) # Ejemplo: 'aK7$mP9@xL2#'
Para contraseñas seguras, prefiere el módulo secrets, que utiliza fuentes criptográficamente seguras.
3. Simulación de Monte Carlo
Una de las aplicaciones más poderosas: estimar el valor de Pi usando el método de Monte Carlo:
import random
def estimarpi(puntos=100000):
dentro = 0
for in range(puntos):
x, y = random.random(), random.random()
if xx + yy <= 1:
dentro += 1
return 4 * dentro / puntos
print(f'Pi estimado: {estimar_pi()}') # ~3.1415
4. División Entreno-Prueba para Machine Learning
import random
datos = list(range(100))
random.shuffle(datos)
split = int(0.8 * len(datos))
entreno = datos[:split]
prueba = datos[split:]
print(f'Entreno: {len(entreno)} muestras')
print(f'Prueba: {len(prueba)} muestras')
Random vs NumPy Random vs Secrets
Python ofrece tres enfoques principales para la aleatoriedad:
| Módulo | Cuándo Usarlo | Rendimiento |
|---|---|---|
random |
Uso general, juegos, scripts simples | Bueno |
numpy.random |
Grandes volúmenes de datos, arrays multidimensionales | Excelente (vectorizado) |
secrets |
Contraseñas, tokens, criptografía | Moderado |
NumPy random es significativamente más rápido para grandes conjuntos de datos porque genera arrays completos de una sola vez usando código C optimizado. El módulo secrets es obligatorio cuando la seguridad es prioritaria.
Mejores Prácticas
- Siempre usa una semilla para reproducibilidad en experimentos y pruebas científicas. Define la semilla al inicio del script y documenta qué valor usaste.
- No uses random para criptografía — prefiere el módulo
secretspara tokens, contraseñas y cualquier dato que deba ser impredecible para un atacante. - Documenta tus semillas para que otros investigadores puedan replicar tus resultados. Una buena práctica es usar la marca de tiempo como semilla por defecto, pero permitir su configuración externa.
- Prefiere numpy.random para grandes volúmenes de datos, especialmente en ciencia de datos y machine learning.
- Cuidado con shuffle en listas grandes — modifica la lista in-place. Si necesitas preservar la original, haz una copia con
copia = lista.copy()antes de mezclar. - Prueba tus generadores: verifica siempre que los valores generados estén dentro de los rangos esperados, especialmente en aplicaciones críticas como simulaciones financieras o médicas.
Rendimiento y Limitaciones
El módulo random usa el algoritmo Mersenne Twister (MT19937), que es rápido y pasa la mayoría de las pruebas estadísticas de aleatoriedad. Sin embargo, no es adecuado para:
- Criptografía (usa
secrets) - Simulaciones que requieren enormes cantidades de números aleatorios (prefiere NumPy)
- Aplicaciones sensibles a patrones de período largo
El período del Mersenne Twister es 2^19937 − 1, más que suficiente para prácticamente cualquier aplicación no criptográfica. En términos prácticos, esto significa que puedes generar billones de números antes de que el ciclo se repita. Para aplicaciones que exigen aún más rendimiento, NumPy implementa el mismo algoritmo en C con vectorización, siendo hasta 50 veces más rápido para grandes volúmenes.
Para aprender más sobre el algoritmo, el artículo de GeeksforGeeks tiene un excelente análisis técnico.
Conclusión
El módulo random de Python es una herramienta potente y versátil que todo desarrollador debería dominar. Desde simples lanzamientos de dados hasta complejas simulaciones de Monte Carlo, proporciona la funcionalidad esencial para trabajar con aleatoriedad de forma productiva y confiable.
Resumen de las funciones más importantes:
random()— float en [0, 1)randint(a, b)— entero entre a y bchoice(seq)— un elemento aleatoriosample(pop, k)— muestra sin reposiciónshuffle(lista)— mezcla in-placeseed(n)— define semilla para reproducibilidad
No olvides consultar la documentación oficial para explorar todas las funciones disponibles. Practica con los ejemplos de este artículo y pronto usarás el módulo random con confianza en tus proyectos.
Para continuar aprendiendo, visita también el tutorial interactivo de PYnative y los ejemplos de W3Schools sobre random.