Python Random: Generate Random Numbers, Choices, and Samples
Updated on
Generating random data is fundamental to programming -- from shuffling a playlist and sampling survey respondents to running Monte Carlo simulations and creating test datasets. But Python's random module has dozens of functions, and it's easy to use the wrong one. Calling random.random() when you need an integer, using choice() when you need multiple unique items, or forgetting that random is not cryptographically secure can lead to subtle bugs or security vulnerabilities.
Python's random module provides a comprehensive toolkit for pseudo-random number generation. This guide covers every function you'll commonly need, with clear examples showing when to use each one.
Random Integers
randint(a, b)
Returns a random integer N such that a <= N <= b (both endpoints included).
import random
# Random integer between 1 and 10 (inclusive)
print(random.randint(1, 10)) # e.g., 7
# Simulate a dice roll
dice = random.randint(1, 6)
print(f"You rolled a {dice}")
# Generate random ages for test data
ages = [random.randint(18, 65) for _ in range(5)]
print(ages) # e.g., [34, 52, 21, 45, 28]randrange(start, stop, step)
Like range() but returns a random element. The stop value is excluded.
import random
# Random even number between 0 and 100
print(random.randrange(0, 101, 2)) # e.g., 42
# Random number from 0 to 9
print(random.randrange(10)) # e.g., 7
# Random multiple of 5 from 0 to 100
print(random.randrange(0, 101, 5)) # e.g., 35Random Floats
random()
Returns a random float in the range [0.0, 1.0).
import random
print(random.random()) # e.g., 0.7234...
# Scale to any range: random float between 10 and 20
value = 10 + random.random() * 10
print(value) # e.g., 15.23...uniform(a, b)
Returns a random float N such that a <= N <= b.
import random
# Random temperature between 98.0 and 99.5
temp = random.uniform(98.0, 99.5)
print(f"Temperature: {temp:.1f}F") # e.g., Temperature: 98.7F
# Random price between 9.99 and 29.99
price = round(random.uniform(9.99, 29.99), 2)
print(f"Price: ${price}")gauss(mu, sigma) -- Normal Distribution
import random
# Generate normally distributed values (mean=100, std=15)
iq_scores = [round(random.gauss(100, 15)) for _ in range(10)]
print(iq_scores) # e.g., [112, 95, 103, 88, 107, ...]Random Selections
choice(seq)
Returns a single random element from a non-empty sequence.
import random
colors = ['red', 'blue', 'green', 'yellow', 'purple']
print(random.choice(colors)) # e.g., 'green'
# Random character from a string
print(random.choice('abcdefghij')) # e.g., 'f'choices(population, weights, k)
Returns a list of k elements chosen WITH replacement (duplicates possible). Supports weights.
import random
# Pick 5 random colors (duplicates allowed)
colors = ['red', 'blue', 'green']
print(random.choices(colors, k=5)) # e.g., ['blue', 'red', 'blue', 'green', 'red']
# Weighted selection (red is 5x more likely)
weighted = random.choices(
['red', 'blue', 'green'],
weights=[5, 1, 1],
k=10
)
print(weighted) # Mostly 'red'sample(population, k)
Returns k unique elements chosen WITHOUT replacement (no duplicates).
import random
# Lottery numbers: 6 unique numbers from 1-49
lottery = random.sample(range(1, 50), 6)
print(sorted(lottery)) # e.g., [3, 12, 27, 33, 41, 48]
# Random survey sample
employees = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank']
survey_group = random.sample(employees, 3)
print(survey_group) # e.g., ['Diana', 'Alice', 'Frank']choice vs choices vs sample
| Function | Replacement | Returns | Use Case |
|---|---|---|---|
choice(seq) | N/A (single item) | One element | Pick one random item |
choices(pop, k=n) | With replacement | List of n elements | Weighted random, simulations |
sample(pop, k=n) | Without replacement | List of n unique elements | Lottery, random subsets |
Shuffling
shuffle(seq)
Shuffles a list in place. Returns None.
import random
deck = list(range(1, 53)) # 52 cards
random.shuffle(deck)
print(deck[:5]) # e.g., [37, 12, 48, 3, 21]
# Deal 5 cards
hand = deck[:5]
remaining = deck[5:]Seeds and Reproducibility
Setting a seed makes random output reproducible -- critical for testing and debugging.
import random
random.seed(42)
print(random.randint(1, 100)) # Always 81
print(random.random()) # Always 0.0744...
# Reset seed for same sequence
random.seed(42)
print(random.randint(1, 100)) # 81 again
print(random.random()) # 0.0744... againWhen to Use Seeds
| Scenario | Seed? | Why |
|---|---|---|
| Unit tests | Yes | Reproducible test results |
| Debugging | Yes | Reproduce the exact bug |
| Simulations (analysis) | Yes | Reproducible experiments |
| Games (gameplay) | No | Players expect true randomness |
| Security/crypto | No (use secrets) | Seeds make output predictable |
Generating Test Data
import random
import string
def random_string(length=10):
"""Generate a random alphanumeric string."""
chars = string.ascii_letters + string.digits
return ''.join(random.choices(chars, k=length))
def random_email():
"""Generate a random email address."""
name = random_string(8).lower()
domains = ['gmail.com', 'yahoo.com', 'outlook.com']
return f"{name}@{random.choice(domains)}"
def random_user():
"""Generate a random user record."""
first_names = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve']
last_names = ['Smith', 'Jones', 'Brown', 'Wilson', 'Taylor']
return {
'name': f"{random.choice(first_names)} {random.choice(last_names)}",
'email': random_email(),
'age': random.randint(18, 65),
'score': round(random.uniform(0, 100), 1),
}
# Generate 5 test users
users = [random_user() for _ in range(5)]
for user in users:
print(user)Random and Data Science
For data analysis workflows, the random module helps with sampling, bootstrapping, and creating synthetic datasets. When combined with pandas, you can generate test DataFrames quickly:
import random
import pandas as pd
random.seed(42)
n = 1000
df = pd.DataFrame({
'age': [random.randint(18, 80) for _ in range(n)],
'income': [round(random.gauss(50000, 15000), 2) for _ in range(n)],
'category': random.choices(['A', 'B', 'C'], weights=[5, 3, 2], k=n),
})
print(df.describe())For interactive exploration of your random datasets, PyGWalker (opens in a new tab) turns any pandas DataFrame into a Tableau-style visualization UI inside Jupyter:
import pygwalker as pyg
walker = pyg.walk(df)Security Warning: random vs secrets
The random module is NOT suitable for security purposes. Its output is deterministic and predictable if the seed is known. For passwords, tokens, and cryptographic applications, use the secrets module:
import secrets
# Cryptographically secure random token
token = secrets.token_hex(16)
print(token) # e.g., 'a3f2b8c9d1e4f5a6b7c8d9e0f1a2b3c4'
# Secure random integer
secure_int = secrets.randbelow(100)
# Secure random choice
secure_choice = secrets.choice(['option1', 'option2', 'option3'])| Feature | random | secrets |
|---|---|---|
| Algorithm | Mersenne Twister (PRNG) | OS entropy source (CSPRNG) |
| Deterministic | Yes (with seed) | No |
| Speed | Fast | Slower |
| Use for | Simulations, games, testing | Passwords, tokens, crypto |
| Reproducible | Yes (with seed()) | No |
FAQ
How do I generate a random integer in Python?
Use random.randint(a, b) to get a random integer between a and b (inclusive). For example, random.randint(1, 10) returns a number from 1 to 10. For a range that excludes the upper bound, use random.randrange(start, stop).
What is the difference between random.choice and random.sample?
random.choice(seq) returns a single random element. random.sample(population, k) returns k unique elements without replacement. For selecting multiple items where duplicates are allowed, use random.choices(population, k=n).
How do I make random results reproducible?
Call random.seed(value) before generating random numbers. Using the same seed produces the same sequence of random values every time. This is essential for unit tests and debugging.
Is Python's random module secure?
No. The random module uses the Mersenne Twister algorithm, which is deterministic and predictable. For security-sensitive applications like passwords or tokens, use the secrets module instead, which uses cryptographically secure random sources.
How do I shuffle a list randomly in Python?
Use random.shuffle(my_list) to shuffle a list in place. It modifies the original list and returns None. If you need the original list unchanged, make a copy first: shuffled = my_list.copy(); random.shuffle(shuffled).
Conclusion
Python's random module covers every common randomization need: randint for integers, uniform for floats, choice/choices/sample for selecting from sequences, shuffle for reordering, and seed for reproducibility. Remember the key distinction: choices allows duplicates (with replacement), sample does not (without replacement). And never use random for security -- use secrets instead.