Python's random module generates pseudo-random numbers and provides utilities for sampling, shuffling, and simple probability simulations.
Two key ideas:
- It's pseudo-random (deterministic given a seed).
- It's not cryptographically secure (use
secretsfor security).
Basic Random Numbers
import random
print(random.random()) # float in [0.0, 1.0)
print(random.uniform(10, 20)) # float in [10.0, 20.0]
print(random.randint(1, 6)) # int in [1, 6]
print(random.randrange(0, 10, 2)) # 0,2,4,6,8Common gotcha: randint vs randrange
randint(a, b)includes both endpoints.randrange(a, b)is likerange(a, b)(excludesb).
Choosing Random Elements
import random
items = ["red", "green", "blue"]
print(random.choice(items))
# Multiple choices (with replacement)
print(random.choices(items, k=5))
# Weighted choices
weights = [0.1, 0.2, 0.7]
print(random.choices(items, weights=weights, k=10))
# Sample without replacement
print(random.sample(items, k=2))Shuffling
import random
deck = list(range(1, 53))
random.shuffle(deck)
print(deck[:5])shuffle() mutates in place.
Reproducibility with Seeds
If you want repeatable results (tests, simulations), set a seed.
import random
random.seed(42)
print([random.randint(1, 10) for _ in range(5)])
random.seed(42)
print([random.randint(1, 10) for _ in range(5)]) # same outputYou can seed with an int, float, str, bytes, or None.
Independent RNG Instances (Recommended)
Rather than using the global RNG, create a dedicated one:
import random
rng = random.Random(123)
print(rng.random())
print(rng.randint(1, 6))This is cleaner for libraries and tests.
Distributions
The module includes helpers for common distributions:
import random
# Normal distribution
print(random.gauss(mu=0, sigma=1))
# Log-normal
print(random.lognormvariate(mu=0, sigma=1))
# Exponential (lambda)
print(random.expovariate(lambd=1.5))
# Triangular
print(random.triangular(low=0, high=10, mode=3))
# Beta
print(random.betavariate(alpha=2, beta=5))Simple Simulation: Dice Rolls
import random
from collections import Counter
N = 100_000
rolls = [random.randint(1, 6) for _ in range(N)]
counts = Counter(rolls)
for face in range(1, 7):
print(face, counts[face] / N)Random Strings / IDs (Non-Security)
import random
import string
alphabet = string.ascii_letters + string.digits
def random_id(n=12):
return ''.join(random.choice(alphabet) for _ in range(n))
print(random_id())If this is for auth tokens, password resets, etc. use secrets.
random vs secrets
- Use
randomfor games, sampling, simulations, quick tests. - Use
secretsfor anything security-related.
import secrets
print(secrets.token_hex(16))
print(secrets.choice(["a", "b", "c"]))Practical Testing Pattern
import random
def test_my_algorithm_is_stable():
rng = random.Random(0)
data = [rng.randint(0, 1000) for _ in range(1000)]
# Run algorithm and assert deterministic outcome
result = sorted(data)[:10]
assert result == [0, 0, 2, 2, 3, 3, 4, 4, 6, 6]Summary
The random module is great for non-security randomness:
random(),randint(),randrange()for numberschoice(),sample(),choices()for selectionshuffle()for in-place shufflingseed()andRandom()for reproducibility
For security-sensitive randomness, use secrets.
React to this post: