Skip to content

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., 35

Random 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

FunctionReplacementReturnsUse Case
choice(seq)N/A (single item)One elementPick one random item
choices(pop, k=n)With replacementList of n elementsWeighted random, simulations
sample(pop, k=n)Without replacementList of n unique elementsLottery, 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... again

When to Use Seeds

ScenarioSeed?Why
Unit testsYesReproducible test results
DebuggingYesReproduce the exact bug
Simulations (analysis)YesReproducible experiments
Games (gameplay)NoPlayers expect true randomness
Security/cryptoNo (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'])
Featurerandomsecrets
AlgorithmMersenne Twister (PRNG)OS entropy source (CSPRNG)
DeterministicYes (with seed)No
SpeedFastSlower
Use forSimulations, games, testingPasswords, tokens, crypto
ReproducibleYes (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.

📚