random em Python: números aleatórios, sorteios e amostras
Aprenda o módulo random do Python: random(), randint(), choice(), sample(), shuffle() e seed() para reprodutibilidade. Com exemplos práticos de sorteios, amostragem e dados de teste — e quando usar secrets ou NumPy.
Para gerar números aleatórios em Python, importe o módulo random — que já vem na biblioteca padrão — e use random.randint(1, 100) para um inteiro, random.random() para um float entre 0 e 1, e random.choice(lista) para sortear um item. Nada precisa ser instalado: o random acompanha o Python no Windows, macOS e Linux.
Quem pergunta a um assistente “como sortear nomes em Python?”, “como pegar um item aleatório de uma lista?” ou “como gerar dados de teste?” precisa de mais do que random.random(): sorteios com e sem reposição, pesos, embaralhamento, reprodutibilidade com seed() e — o mais importante — saber que random não serve para senhas e tokens (aí o módulo secrets entra). É o que este guia cobre, com exemplos de sorteios, amostragem de clientes e massa de dados de teste.
Como o random funciona (e por que “aleatório” está entre aspas)
O random implementa o Mersenne Twister, um gerador pseudoaleatório: dado um estado inicial, a sequência é 100% determinística. Parece aleatório, é estatisticamente bom para simulações e sorteios, mas é previsível para quem conhece o estado — por isso nunca use para criptografia.
Três consequências práticas:
- Reprodutível a pedido: com
random.seed(42), toda execução gera a mesma sequência. - Rápido e sem dependências: ideal para scripts, sorteios e testes.
- Não é seguro: para tokens e senhas, use
secrets(que sorteia bytes com o gerador do sistema operacional).
Os números básicos: random, randint, randrange, uniform
import random
random.random() # float entre 0.0 e 1.0 (1.0 excluído)
random.randint(1, 6) # inteiro de 1 a 6 — limites INCLUSOS (dado)
random.randrange(0, 101, 5) # 0, 5, 10, ... 100 (limite superior excluso)
random.uniform(10.0, 20.0) # float entre 10 e 20
random.gauss(170, 8) # distribuição normal: média 170, desvio 8
O detalhe que pega iniciantes: randint(a, b) inclui os dois limites; randrange(a, b) exclui b (como range). Para alturas ou notas com distribuição realista, gauss gera valores em torno da média — útil junto com o módulo statistics para simular e analisar dados.
Sorteios de listas: choice, choices, sample, shuffle
O dia a dia com random é quase sempre sorteio de sequências:
nomes = ["Ana", "Bruno", "Carla", "Diego", "Elisa"]
random.choice(nomes) # 1 item sorteado
random.choices(nomes, k=3) # 3 itens COM reposição (pode repetir)
random.choices(nomes, weights=[1, 1, 1, 1, 8], k=1) # Elisa com 8x mais chance
random.sample(nomes, 3) # 3 itens SEM reposição (não repete)
random.shuffle(nomes) # embaralha a própria lista (in-place)
A regra de ouro: choices com “s” repete itens e aceita pesos; sample não repete. Para o sorteio de brindes da empresa, sample é a resposta — ninguém ganha duas vezes. Para simular jogadas ou chegadas de clientes, choices com pesos descreve melhor a realidade.
shuffle só funciona em listas (mutáveis). Para embaralhar uma tupla sem alterá-la:
embaralhado = random.sample(tuple_nomes, k=len(tuple_nomes))
Reprodutibilidade com seed()
import random
random.seed(42)
print(random.randint(1, 100)) # sempre 82
print(random.choice(nomes)) # sempre o mesmo nome
Sem seed, o Python inicializa o gerador com a hora do sistema e cada execução muda. Com seed:
- Testes ficam determinísticos — o pytest valida o mesmo resultado toda vez.
- Notebooks reexecutam com os mesmos dados “aleatórios”.
- Bugs em sorteios dá para reproduzir item a item.
Um cuidado: chame random.seed() no início e apenas uma vez por execução; chamadas repetidas no meio do código resetam a sequência e geram padrões indesejados. Em testes, prefira criar um gerador isolado:
rng = random.Random(2026) # instância própria — não afeta o global
amostra = rng.sample(clientes, 100)
Exemplos práticos
Sorteio de brindes em um CSV de participantes
import csv
import random
with open("participantes.csv", newline="", encoding="utf-8") as f:
participantes = [linha["nome"] for linha in csv.DictReader(f)]
sorteados = random.sample(participantes, 3) # 3 brindes, sem repetir
print("Ganhadores:", ", ".join(sorteados))
Leitura de CSV detalhada no guia de CSV com Python. Para auditoria, registre a seed usada — qualquer pessoa confere o resultado.
Amostra de clientes para pesquisa
populacao = [f"cliente_{id_}" for id_ in range(1, 5001)]
amostra = random.sample(populacao, 200)
Amostragem simples e sem reposição em uma linha. Quando a análise crescer para DataFrames, o pandas tem df.sample(n=200) com a mesma semântica.
Massa de dados de teste com valores brasileiros
import random
def cpf_teste() -> str:
nove = [random.randint(0, 9) for _ in range(9)]
return "".join(map(str, nove)) # sem dígitos verificadores
usuarios = [{
"id": random.randint(1000, 9999),
"nome": random.choice(["Ana", "Bruno", "Carla", "Diego", "Elisa"]),
"saldo": round(random.uniform(0, 5000), 2),
"cpf_parcial": cpf_teste(),
} for _ in range(500)]
Para dados válidos e realistas (CPF com dígitos verificadores, CEP existente), veja validação de CPF/CNPJ e CEP com BrasilAPI e ViaCEP — as próprias bibliotecas brasileiras geram documentos válidos para teste.
Separar treino e teste de um modelo
random.shuffle(dataset)
corte = int(len(dataset) * 0.8)
treino, teste = dataset[:corte], dataset[corte:]
Funciona para entender a mecânica; na prática use train_test_split do scikit-learn, que aceita random_state e estratificação.
random x secrets x numpy.random
| Preciso de… | Use | Exemplo |
|---|---|---|
| Sorteio, simulação, amostra, dado, teste | random | random.randint(1, 6), random.sample(x, 10) |
| Senha, token, chave de API, URL secreta | secrets | secrets.token_urlsafe(32) |
| Milhões de valores, arrays, distribuições estatísticas | numpy.random | rng.integers(0, 10, size=1_000_000) |
random: o padrão para scripts e sorteios. Pseudoaleatório, nunca para criptografia — para isso existe o guia de tokens e senhas com secrets.secrets: sorteia bytes do sistema operacional, imprevisível. Escolha certa para qualquer segredo.numpy.random: vetorizado, muito mais rápido em escala, com gerador (default_rng()) recomendado. Veja a introdução ao NumPy.
Erros comuns
- Usar
randompara senhas/tokens — o Mersenne Twister é previsível; usesecrets. - Confundir
randintcomrandrange—randint(1, 6)inclui o 6;randrange(1, 6)para no 5. - Usar
choicesquando o sorteio não pode repetir — brindes e amostras pedemsample. shuffleem tupla ou string — só aceita listas; converta comlist()antes.- Chamar
seed()no meio do loop — reseta a sequência e cria padrões repetidos. - Seed global compartilhada entre módulos — prefira
random.Random(seed)isolado por teste.
Checklist rápido
- O caso é sorteio/amostra/simulação (e não segurança)?
- Escolhi
samplequando itens não podem repetir? - Passei
weightsquando as chances não são iguais? - Registrei a
seedpara reprodutibilidade em testes e auditoria? - Para senhas e tokens, troquei por
secrets? - Em escala grande, avaliei
numpy.random.default_rng()?
Conclusão
O módulo random resolve a pergunta “como sortear/gerar aleatório em Python?” com funções diretas: randint para inteiros, uniform para floats, choice/choices para itens (com pesos), sample para amostras sem reposição, shuffle para embaralhar e seed para reprodutibilidade. Ele já vem no Python, não precisa de ambiente virtual para funcionar — embora usar um venv continue sendo boa prática para o projeto. Guarde a regra de segurança: segredo é com secrets; sorteio e simulação são com random.
Próximos passos naturais neste site: senhas e tokens seguros com secrets, UUIDs e identificadores únicos, estatística descritiva com statistics e sorteios de dados com pygame.