---
title: "random em Python: números aleatórios, sorteios e amostras"
url: "https://python.dev.br/blog/python-random-numeros-aleatorios/"
markdown_url: "https://python.dev.br/blog/python-random-numeros-aleatorios.MD"
description: "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."
date: "2026-09-30"
author: "Equipe Python Dev BR"
---

# 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](/blog/python-secrets-tokens-senhas-seguros/) 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

```python
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](/blog/python-statistics-media-mediana-desvio-padrao/) para simular e analisar dados.

## Sorteios de listas: choice, choices, sample, shuffle

O dia a dia com `random` é quase sempre sorteio de sequências:

```python
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:

```python
embaralhado = random.sample(tuple_nomes, k=len(tuple_nomes))
```

## Reprodutibilidade com seed()

```python
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](/guias/testes-com-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:

```python
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

```python
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](/blog/python-csv-leitura-escrita-arquivos/). Para auditoria, registre a seed usada — qualquer pessoa confere o resultado.

### Amostra de clientes para pesquisa

```python
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](/blog/introducao-ao-pandas/) tem `df.sample(n=200)` com a mesma semântica.

### Massa de dados de teste com valores brasileiros

```python
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](/blog/validar-cpf-cnpj-cep-python-brasilapi-viacep/) — as próprias bibliotecas brasileiras geram documentos válidos para teste.

### Separar treino e teste de um modelo

```python
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](/blog/introducao-ao-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](/blog/python-secrets-tokens-senhas-seguros/).
- **`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](/blog/introducao-ao-numpy/).

## Erros comuns

1. **Usar `random` para senhas/tokens** — o Mersenne Twister é previsível; use `secrets`.
2. **Confundir `randint` com `randrange`** — `randint(1, 6)` inclui o 6; `randrange(1, 6)` para no 5.
3. **Usar `choices` quando o sorteio não pode repetir** — brindes e amostras pedem `sample`.
4. **`shuffle` em tupla ou string** — só aceita listas; converta com `list()` antes.
5. **Chamar `seed()` no meio do loop** — reseta a sequência e cria padrões repetidos.
6. **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 `sample` quando itens não podem repetir?
- [ ] Passei `weights` quando as chances não são iguais?
- [ ] Registrei a `seed` para 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](/guias/criando-virtual-environment/) 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](/blog/python-secrets-tokens-senhas-seguros/), [UUIDs e identificadores únicos](/blog/python-uuid-identificadores-unicos/), [estatística descritiva com statistics](/blog/python-statistics-media-mediana-desvio-padrao/) e [sorteios de dados com pygame](/blog/criando-jogos-com-pygame/).
