El módulo random de Python permite generar valores pseudoaleatorios, elegir elementos de una colección, mezclar listas y crear muestras sin instalar paquetes adicionales. Forma parte de la biblioteca estándar y resulta útil en juegos, simulaciones, pruebas, generación de datos ficticios y ejercicios de programación. Sin embargo, no debe utilizarse para contraseñas, tokens de acceso ni operaciones criptográficas, porque sus resultados son predecibles para un atacante que conozca suficiente información sobre el estado interno del generador.
Antes de empezar, conviene dominar las listas en Python, los bucles for y while y la creación de funciones reutilizables. Estos conceptos aparecen constantemente cuando trabajamos con datos aleatorios.
Importar el módulo random
La importación básica es directa:
import randomA partir de ese momento puedes utilizar las funciones mediante el prefijo random.. Evita llamar a tu propio archivo random.py, porque Python podría importar ese archivo local en lugar del módulo oficial y producir errores difíciles de interpretar.
Generar números enteros aleatorios
random.randint(a, b) devuelve un entero entre ambos límites, incluyendo tanto a como b:
import random
dado = random.randint(1, 6)
print(dado)Este comportamiento inclusivo es importante. Si necesitas un valor siguiendo la lógica de range(), donde el límite final queda excluido, puedes usar random.randrange():
numero = random.randrange(0, 100, 5)
print(numero)El ejemplo produce un múltiplo de cinco desde cero hasta noventa y cinco. Los parámetros funcionan como range(inicio, fin, paso).
Generar números decimales
random.random() devuelve un número de punto flotante mayor o igual que cero y menor que uno:
probabilidad = random.random()
print(probabilidad)Para seleccionar un decimal dentro de otro intervalo utiliza uniform(a, b):
temperatura = random.uniform(18.0, 30.0)
print(f"Temperatura simulada: {temperatura:.2f} °C")Los números de punto flotante tienen limitaciones de precisión. No conviene utilizarlos para cálculos financieros exactos sin comprender su representación.
Elegir un elemento de una lista
choice() selecciona un elemento de una secuencia no vacía:
colores = ["rojo", "verde", "azul", "amarillo"]
elegido = random.choice(colores)
print(elegido)Si la lista está vacía, Python lanza IndexError. En datos recibidos desde un archivo o una API, valida primero que existan elementos:
if colores:
print(random.choice(colores))
else:
print("No hay colores disponibles")Elegir varios elementos
random.choices() permite elegir varios elementos y admite repeticiones:
premios = ["descuento", "puntos", "envío gratis"]
resultados = random.choices(premios, k=5)
print(resultados)También puedes definir pesos para que algunas opciones sean más probables:
estado = random.choices(
["aprobado", "pendiente", "rechazado"],
weights=[70, 20, 10],
k=1
)[0]Los pesos son proporcionales; no necesitan sumar cien.
Crear una muestra sin repeticiones
random.sample() elige elementos únicos:
participantes = ["Ana", "Luis", "Marta", "Pablo", "Sofía"]
ganadores = random.sample(participantes, k=2)
print(ganadores)El tamaño de la muestra no puede superar la cantidad de elementos disponibles. Si k es mayor, se produce ValueError. Esta función es apropiada para sorteos sencillos, selección de conjuntos de prueba o creación de equipos sin repetir personas.
Mezclar una lista con shuffle
shuffle() modifica una lista existente y no devuelve una nueva:
cartas = ["A", "K", "Q", "J", "10"]
random.shuffle(cartas)
print(cartas)Un error frecuente es escribir cartas = random.shuffle(cartas). En ese caso, cartas termina valiendo None. Si necesitas conservar la lista original, crea una copia antes de mezclarla:
mezcladas = cartas.copy()
random.shuffle(mezcladas)Reproducir resultados con seed
En pruebas y experimentos es útil obtener siempre la misma secuencia. Para ello se establece una semilla:
random.seed(42)
print(random.randint(1, 100))
print(random.randint(1, 100))Usar la misma semilla y la misma secuencia de llamadas suele reproducir los resultados en el mismo entorno. Esto facilita depurar simulaciones, comparar algoritmos y escribir tests. No conviertas una semilla fija en un mecanismo de seguridad: precisamente su objetivo es hacer la secuencia reproducible.
Usar una instancia independiente
Los programas grandes pueden crear generadores separados para evitar que una parte del código altere la secuencia global:
generador = random.Random(1234)
print(generador.randint(1, 10))
print(generador.choice(["A", "B", "C"]))Esta técnica mejora la organización de simulaciones y pruebas porque cada componente controla su propio estado.
Ejemplo: juego de adivinación
import random
secreto = random.randint(1, 20)
intentos = 5
while intentos > 0:
try:
numero = int(input("Adivina un número del 1 al 20: "))
except ValueError:
print("Escribe un número entero.")
continue
if numero == secreto:
print("¡Correcto!")
break
elif numero < secreto:
print("El número secreto es mayor.")
else:
print("El número secreto es menor.")
intentos -= 1
print(f"Intentos restantes: {intentos}")
else:
print(f"El número era {secreto}.")El ejemplo combina números aleatorios, validación de entrada, condiciones y un bucle. Para proyectos reales, separa la lógica en funciones y crea pruebas para los casos principales.
random no sirve para seguridad
El generador del módulo random está diseñado para simulación y modelado, no para proteger información. Para contraseñas, enlaces de recuperación, códigos de verificación o tokens utiliza el módulo secrets. La guía sobre números aleatorios seguros con secrets muestra la diferencia práctica.
La documentación oficial de random describe todas las distribuciones disponibles, el generador Mersenne Twister y las funciones para secuencias. La documentación oficial de secrets explica qué herramientas utilizar cuando la imprevisibilidad es un requisito de seguridad.
Errores frecuentes
Los problemas más comunes son confundir los límites inclusivos de randint(), intentar obtener más elementos de los disponibles con sample(), asignar el resultado de shuffle(), usar una lista vacía con choice() y emplear random para generar credenciales. También debes evitar depender de una distribución aleatoria para ocultar errores de lógica. Una semilla fija durante las pruebas ayuda a reproducir el problema.
Conclusión
El módulo random cubre la mayoría de las necesidades de aleatoriedad no criptográfica. randint() genera enteros, uniform() produce decimales, choice() selecciona un elemento, sample() evita repeticiones y shuffle() mezcla listas. La clave es elegir la función correcta, validar las colecciones y distinguir entre simulación y seguridad. Con estas precauciones puedes construir juegos, datos de prueba y experimentos reproducibles de forma clara y confiable.






