W3docs

Módulo random do Python

Aprenda o módulo random do Python: gere números aleatórios, faça escolhas ponderadas, embaralhe sequências, use seed para reprodutibilidade e randomness criptográfica.

O módulo random integrado do Python gera números pseudoaleatórios e faz seleções aleatórias. Ele é baseado no algoritmo Mersenne Twister, que produz sequências pseudoaleatórias de alta qualidade adequadas para simulações, jogos, amostragem e testes — mas não para fins sensíveis à segurança, como geração de senhas ou chaves criptográficas. Este capítulo aborda:

  • Geração de floats, inteiros e intervalos aleatórios
  • Escolha de elementos aleatórios: choice, choices, sample
  • Embaralhamento de sequências no local com shuffle
  • Uso de seed para resultados reproduzíveis
  • Distribuições contínuas: uniform, gauss, triangular
  • Quando usar secrets em vez de random

Nenhuma instalação é necessária — import random é tudo que você precisa.

Importando o módulo

import random

Todos os exemplos abaixo assumem que esta importação está no escopo. Você também pode importar funções individuais para evitar o prefixo random., embora o prefixo deixe claro de onde cada função vem:

from random import randint, choice, shuffle

Gerando floats aleatórios

random()

random.random() retorna um float em [0.0, 1.0) — incluindo 0.0, mas nunca chegando a 1.0.

import random

print(random.random())  # e.g. 0.6394267984578837
print(random.random())  # e.g. 0.025010755222666936

O valor muda a cada chamada porque o gerador avança seu estado interno.

uniform(a, b)

random.uniform(a, b) retorna um float N tal que a <= N <= b:

import random

random.seed(42)
print(random.uniform(1.5, 10.5))  # 7.254841186120954
print(random.uniform(-1.0, 1.0))  # e.g. -0.82  (some float in [-1, 1])

Ao contrário de random(), uniform permite especificar ambos os extremos do intervalo, e o limite superior pode ser retornado.

Gerando inteiros aleatórios

randint(a, b)

random.randint(a, b) retorna um inteiro aleatório N tal que a <= N <= b. Ambos os extremos são inclusivos:

import random

random.seed(42)
die = random.randint(1, 6)
print(die)  # 6

Esta é a forma mais comum de simular lançamentos de dados, sorteios de cartas ou qualquer intervalo de inteiros discreto.

randrange(start, stop[, step])

random.randrange espelha o range() do Python — stop é exclusivo e você pode especificar um passo:

import random

random.seed(42)
# Pick an even number from 0 to 98 (0, 2, 4, ..., 98)
print(random.randrange(0, 100, 2))   # e.g. a random even integer

# Pick a multiple of 5 from 0 to 95
random.seed(42)
print(random.randrange(0, 100, 5))   # 15

Quando você precisa de inteiros aleatórios de um intervalo que não começa em 0 ou precisa de um passo, randrange é mais expressivo que randint.

getrandbits(k)

random.getrandbits(k) retorna um inteiro não negativo aleatório com exatamente k bits aleatórios:

import random

random.seed(42)
print(random.getrandbits(8))   # 163 (an integer in 0..255)
print(random.getrandbits(16))  # an integer in 0..65535

Isso é útil quando você precisa de inteiros aleatórios maiores do que os usados com randint, ou quando está trabalhando no nível de bits.

Escolhendo de sequências

choice(seq)

random.choice(seq) escolhe um elemento aleatoriamente de uma sequência não vazia. Funciona com listas, tuplas e strings:

import random

random.seed(42)
fruits = ['apple', 'banana', 'cherry']
print(random.choice(fruits))    # cherry

random.seed(42)
print(random.choice('ABCDE'))   # A  (picks one character)

Se a sequência estiver vazia, um IndexError é lançado.

choices(population, weights=None, k=1)

random.choices escolhe k elementos com substituição (o mesmo elemento pode aparecer mais de uma vez). Você pode influenciar a seleção com weights:

import random

colors = ['red', 'blue', 'green']

# Equal probability — each run may differ
print(random.choices(colors, k=3))
# e.g. ['blue', 'red', 'red']

# Weighted: green is 3× more likely than red, blue is 2×
random.seed(42)
print(random.choices(colors, weights=[1, 2, 3], k=4))
# ['green', 'red', 'blue', 'blue']

choices sempre retorna uma lista, mesmo quando k=1. O argumento weights é relativo — [1, 2, 3] dá a mesma distribuição que [10, 20, 30].

sample(population, k)

random.sample escolhe k elementos sem substituição — cada elemento pode aparecer apenas uma vez no resultado. Ele não modifica a sequência original:

import random

random.seed(42)
# Pick 4 unique numbers from 0-9
print(random.sample(range(10), 4))  # [1, 0, 4, 9]

# Simulate a lottery: 6 unique numbers from 1-49
random.seed(7)
ticket = sorted(random.sample(range(1, 50), 6))
print(ticket)  # [4, 5, 10, 21, 26, 42]

Se k for maior que o tamanho da população, random.sample lança um ValueError:

import random

try:
    random.sample([1, 2, 3], 5)
except ValueError as e:
    print(e)  # Sample larger than population or is negative

choices vs sample em resumo:

choicessample
SubstituiçãoSimNão
Resultados duplicadosPossívelNunca
Modifica o originalNãoNão
Suporta pesosSimNão (use choices)

Embaralhando sequências

random.shuffle(seq) embaralha a lista no local e retorna None. A lista original é modificada:

import random

random.seed(42)
deck = [1, 2, 3, 4, 5]
random.shuffle(deck)
print(deck)  # [4, 2, 3, 5, 1]  (original list is modified)

Se você precisar de uma cópia embaralhada sem alterar o original, use random.sample:

import random

random.seed(42)
original = [1, 2, 3, 4, 5]
shuffled = random.sample(original, len(original))
print(original)  # [1, 2, 3, 4, 5]  (unchanged)
print(shuffled)  # [4, 2, 3, 5, 1]

Usando seed para resultados reproduzíveis

Por padrão, o módulo random inicializa sua seed a partir do tempo do sistema (ou os.urandom()), então cada execução produz valores diferentes. Chamar random.seed() com um valor fixo bloqueia a sequência para que você obtenha saída idêntica toda vez — essencial para depuração, testes unitários e simulações reproduzíveis:

import random

random.seed(42)
print(random.random())          # 0.6394267984578837
print(random.randint(1, 10))    # 1
print(random.choice(['a', 'b', 'c']))  # c

# Reset to the same seed — identical sequence
random.seed(42)
print(random.random())          # 0.6394267984578837  (same as before)
print(random.randint(1, 10))    # 1
print(random.choice(['a', 'b', 'c']))  # c

random.seed() aceita um inteiro, uma string, um float, bytes ou None (que reinicializa a partir do sistema). A seed é uma operação global — afeta todas as chamadas subsequentes no mesmo programa, portanto, defina a seed uma vez no início de um bloco reproduzível.

Gerando dados de teste reproduzíveis

import random

random.seed(999)
test_scores = [round(random.uniform(0, 100), 2) for _ in range(5)]
print(test_scores)  # [78.13, 8.01, 87.25, 57.38, 49.06]

Cada execução com seed(999) produz exatamente a mesma lista, tornando isso útil para testes unitários que verificam valores específicos.

Distribuições contínuas

O módulo random inclui várias distribuições de probabilidade contínuas, úteis em simulações e modelagem estatística.

uniform(a, b)

Já abordado acima — uma distribuição plana onde cada valor em [a, b] é igualmente provável.

triangular(low, high, mode)

Retorna um float de uma distribuição triangular onde mode é o valor mais comum:

import random

random.seed(42)
# Most values cluster near 5, between 0 and 10
t = random.triangular(0, 10, 5)
print(t)  # 5.753983033817951

Útil quando você conhece o valor mínimo, máximo e mais provável, mas não a distribuição exata — comum em estimativas de projetos e modelagem de risco.

gauss(mu, sigma)

Retorna um float de uma distribuição Gaussiana (normal) com média mu e desvio padrão sigma:

import random

random.seed(42)
# Heights in cm: mean 170, std 10
heights = [round(random.gauss(170, 10), 1) for _ in range(5)]
print(heights)  # [168.6, 168.3, 168.9, 177.0, 168.7]

random.normalvariate(mu, sigma) é equivalente, mas seguro para threads; use normalvariate em programas com múltiplas threads.

expovariate(lambd)

Retorna um float de uma distribuição exponencial, onde lambd é 1 / média. Útil para modelar o tempo entre eventos (por exemplo, chegadas de clientes, pacotes de rede):

import random

random.seed(42)
# Mean inter-arrival time = 5 minutes; lambd = 1/5
wait = random.expovariate(1 / 5)
print(round(wait, 2))  # 5.1  (minutes until next arrival)

Exemplos práticos

Simulando 60 lançamentos de dados

import random

random.seed(42)
counts = {face: 0 for face in range(1, 7)}
for _ in range(60):
    counts[random.randint(1, 6)] += 1

print(counts)
# {1: 15, 2: 10, 3: 8, 4: 7, 5: 10, 6: 10}

Com mais lançamentos, a distribuição se aproxima da probabilidade teórica de 1/6 para cada face.

Escolhendo um time aleatório

import random

random.seed(42)
players = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve', 'Frank']
random.shuffle(players)

team_a = players[:3]
team_b = players[3:]
print('Team A:', team_a)
print('Team B:', team_b)

Senha aleatória simples

Para contextos não relacionados à segurança (demonstrações, tokens descartáveis), random.choices funciona bem:

import random
import string

random.seed(42)
chars = string.ascii_letters + string.digits
password = ''.join(random.choices(chars, k=12))
print(password)  # NbrnTP3fAbnF

Para senhas ou tokens de usuário reais, use o módulo secrets (veja abaixo).

Quando usar secrets em vez de random

O módulo random não é criptograficamente seguro. Um invasor que observe saída suficiente pode prever valores futuros. Para qualquer coisa sensível à segurança, use o módulo secrets (Python 3.6+), que obtém dados da fonte aleatória criptográfica do sistema operacional:

import secrets

# Cryptographically secure random integer in [0, 100)
print(secrets.randbelow(100))

# Secure random token for a password-reset link (URL-safe base64)
token = secrets.token_urlsafe(32)
print(token)  # e.g. 'gIg9XzExxFkHLAH9JCK8Zxb1aBEFZ...'

# Secure random hex string for an API key
api_key = secrets.token_hex(16)
print(api_key)  # e.g. 'a3f1c2d4e5b6...'

Regra geral: se você estiver gerando tokens, IDs de sessão, senhas ou qualquer valor que um adversário não deve ser capaz de adivinhar, use secrets. Use random para todo o resto (jogos, simulações, dados de teste, amostragem).

Referência rápida

FunçãoDescriçãoRetorna
random.random()Float em [0.0, 1.0)float
random.uniform(a, b)Float em [a, b]float
random.randint(a, b)Inteiro em [a, b] (ambos inclusivos)int
random.randrange(start, stop[, step])Inteiro de range(start, stop, step)int
random.getrandbits(k)Inteiro não negativo com k bits aleatóriosint
random.choice(seq)Um elemento aleatóriotipo do elemento
random.choices(pop, weights, k)k elementos com substituiçãolist
random.sample(pop, k)k elementos sem substituiçãolist
random.shuffle(seq)Embaralha lista no localNone
random.seed(a)Define a seed aleatóriaNone
random.gauss(mu, sigma)Variante Gaussiana (normal)float
random.normalvariate(mu, sigma)Variante normal (seguro para threads)float
random.triangular(low, high, mode)Variante de distribuição triangularfloat
random.expovariate(lambd)Variante de distribuição exponencialfloat

Capítulos relacionados

Prática

Prática
Which function picks elements without replacement (each item can appear only once in the result)?
Which function picks elements without replacement (each item can appear only once in the result)?
Was this page helpful?