Randomness is a fundamental building block in programming. Whether you are simulating a dice roll, shuffling a playlist, generating test data, or picking a winner from a list, Python's built-in random module gives you everything you need with a single import. This tutorial walks through every essential function from the ground up, so you can start randomizing numbers in your own scripts today.
If you have ever wondered how games produce unpredictable outcomes or how automated tests generate sample data on the fly, the answer almost always traces back to a random number generator. Python ships with one in the standard library, which means there is nothing to install. You just import it and start calling functions.
What Is the random Module and Why Does It Exist?
The random module is part of Python's standard library. It implements pseudo-random number generators for a variety of distributions. "Pseudo-random" means the numbers are not truly random in the mathematical sense. They are produced by a deterministic algorithm that starts from an initial value called a seed. Given the same seed, the sequence of numbers will always be identical.
Under the hood, Python uses the Mersenne Twister algorithm as its core generator. It produces 53-bit precision floats and has a period of 2**19937-1, which is an astronomically large number. For simulations, games, and general-purpose programming, this level of randomness is more than adequate.
The random module is not safe for security purposes. Its output is predictable if the seed is known. For passwords, authentication tokens, or anything security-sensitive, use the secrets module instead.
To start using the module, add this single line at the top of your Python file:
import random
That single import unlocks every function covered in this tutorial. No pip install required.
Generating Random Integers
Whole numbers are the starting point for randomization. Python gives you two primary functions for generating random integers: randint() and randrange().
random.randint(a, b)
This function returns a random integer N such that a <= N <= b. Both endpoints are included. Think of it as rolling a die where every face between a and b is possible.
import random
# Simulate a six-sided dice roll
dice_roll = random.randint(1, 6)
print(dice_roll) # Could print any integer from 1 to 6
# Generate a random number between 1 and 100
score = random.randint(1, 100)
print(score) # Could print any integer from 1 to 100
random.randrange(start, stop, step)
This function mirrors how Python's built-in range() works. The stop value is excluded, and you can optionally provide a step. This is useful when you need random even numbers, random multiples of five, or any other stepped pattern.
import random
# Random integer from 0 to 9 (10 is excluded)
digit = random.randrange(10)
print(digit) # 0, 1, 2, ... or 9
# Random even number between 0 and 20
even = random.randrange(0, 21, 2)
print(even) # 0, 2, 4, 6, ... or 20
# Random multiple of 5 between 5 and 50
multiple = random.randrange(5, 51, 5)
print(multiple) # 5, 10, 15, ... or 50
If you only need a single random integer with both endpoints included, randint() is the simpler choice. Reach for randrange() when you need to skip values with a step or want the same exclusive-stop behavior as range().
Build the statement that generates a random integer between 1 and 10 (inclusive):
Generating Random Floats
When you need decimal numbers rather than whole numbers, the random module provides two primary options.
random.random()
Called with no arguments, random.random() returns a floating-point number in the half-open range [0.0, 1.0). That means 0.0 is a possible result, but 1.0 is not. This is the foundational function that many other random functions are built on top of internally.
import random
# Generate a random float between 0.0 and 1.0
value = random.random()
print(value) # e.g., 0.37444887175646646
random.uniform(a, b)
When you need a float within a specific range, uniform() is the function to use. It returns a number N where a <= N <= b.
import random
# Random temperature between 36.0 and 42.0
temperature = random.uniform(36.0, 42.0)
print(f"Body temp: {temperature:.1f}") # e.g., Body temp: 37.8
# Random price between 9.99 and 49.99
price = random.uniform(9.99, 49.99)
print(f"Price: ${price:.2f}") # e.g., Price: $23.47
- Returns
- Random integer, both endpoints included
- Example
- randint(1, 6) can return 1, 2, 3, 4, 5, or 6
- Returns
- Random integer, stop excluded, optional step
- Example
- randrange(0, 10, 2) returns 0, 2, 4, 6, or 8
- Returns
- Float in [0.0, 1.0), no arguments needed
- Example
- random.random() might return 0.8147236541
- Returns
- Float in [a, b], custom range
- Example
- uniform(1.5, 9.5) might return 4.2783
This code is supposed to simulate rolling two dice and printing the total. One line has a mistake. Can you find it?
random.randint(0, 6) to random.randint(1, 6). A standard die has faces numbered 1 through 6. Starting at 0 means the second die could roll a zero, which is not a valid dice value and would produce incorrect totals.
Working with Sequences: choice, sample, and shuffle
Random numbers are not just about generating digits. You often need to randomly select from a list, pick multiple unique items, or reorder a collection. The random module handles all of these.
random.choice(sequence)
Picks a single random element from a non-empty sequence such as a list, tuple, or string.
import random
colors = ["red", "green", "blue", "yellow"]
winner = random.choice(colors)
print(f"The winning color is {winner}")
random.sample(population, k)
Returns k unique elements from a population. This is selection without replacement, so no item appears twice in the result.
import random
# Pick 3 unique lottery numbers from 1 to 49
lottery = random.sample(range(1, 50), 3)
print(lottery) # e.g., [17, 42, 3]
random.shuffle(list)
Reorders a list in place and returns None. The original list is modified directly. If you need the original list unchanged, copy it first.
import random
deck = list(range(1, 53)) # 52 cards
random.shuffle(deck)
hand = deck[:5]
print(f"Your hand: {hand}")
random.choices(population, k=n) is a related function that selects with replacement, meaning the same item can appear more than once. Use sample() when duplicates are not allowed and choices() when they are.
Controlling Randomness with seed()
Sometimes you need your "random" results to be predictable. Testing is the classic example. If a test relies on random data and the data changes every run, it becomes impossible to reproduce failures. The seed() function solves this by locking the generator to a known starting point.
import random
random.seed(42)
print(random.randint(1, 100)) # Always prints the same number
print(random.random()) # Always prints the same float
# Reset the seed to get the same sequence again
random.seed(42)
print(random.randint(1, 100)) # Same number as the first call above
When you call random.seed() with no argument (or pass None), Python seeds the generator from the current system time or an operating-system-provided source of randomness. This is the default behavior when you first import the module, which is why you get different results each time you run a script normally.
A common pattern in test files is to set random.seed() once at the top of a test function or in a setup method. This guarantees every assertion sees the same data across runs while keeping the rest of your application fully random.
How to Generate Random Numbers in Python
Follow these four steps to go from an empty script to a working random number generator.
-
Import the random module
At the top of your Python file, write
import random. This gives you access to every function in the module. No installation is needed because random is part of the standard library. -
Choose the right function for your data type
Use
random.randint(a, b)for a random integer between a and b inclusive. Userandom.random()for a float between 0 and 1. Userandom.uniform(a, b)for a float within a custom range. Match the function to the type of number your program needs. -
Call the function and store the result
Assign the return value to a variable, such as
result = random.randint(1, 100). You can then print it, use it in a calculation, or pass it to another function. Each call produces a new random value. -
Verify your output by running the script multiple times
Run your script two or three times and confirm the output changes each run. If the numbers stay the same, check for a fixed
random.seed()call in your code. Different output on each run confirms the randomizer is working correctly.
Python Learning Summary Points
- The
randommodule is part of the standard library and requires onlyimport randomto use. It relies on the Mersenne Twister algorithm, which is suitable for simulations and general-purpose randomization but not for security. - Use
randint(a, b)for integers with both endpoints included,randrange(start, stop, step)for range-like integer selection,random()for a float between 0 and 1, anduniform(a, b)for a float in a custom range. - For sequences,
choice()picks one item,sample()picks multiple unique items without replacement, andshuffle()reorders a list in place. - The
seed()function makes random output reproducible. Pass a fixed value for consistent results during testing, or pass no argument for system-seeded randomness. - Never use the
randommodule for security-sensitive tasks. Use thesecretsmodule instead for passwords, tokens, and authentication.
Randomization is something you will reach for repeatedly as you build Python projects. Start with the basic functions covered here, and you will have the tools to handle dice rolls, random selections, shuffled lists, and reproducible test data from day one.
Frequently Asked Questions
random.randint(a, b) returns a random integer where both a and b are included in the possible results. random.randrange(start, stop, step) works like range() and excludes the stop value. For example, randint(1, 10) can return 10, but randrange(1, 10) cannot.
Call random.random() with no arguments. It returns a floating-point number in the range 0.0 up to but not including 1.0. For a custom range, use random.uniform(a, b) instead.
No. The random module uses the Mersenne Twister algorithm, which is deterministic and predictable if the seed is known. For passwords, tokens, and security-sensitive applications, use the secrets module instead.
random.seed() initializes the random number generator with a specific starting value. When you pass the same seed value, the sequence of random numbers produced will be identical every time. This is useful for testing and reproducing results.
Use random.choice(your_list) to select one random item. To select multiple unique items, use random.sample(your_list, k) where k is how many items you want. To select multiple items with possible repeats, use random.choices(your_list, k=n).
This happens when random.seed() is called with a fixed value somewhere in your code. Remove the seed call or use random.seed() with no argument to seed from the current system time, which produces different results on each run.
Call random.shuffle(your_list) to reorder the list in place. This modifies the original list and returns None. If you need the original unchanged, make a copy first with shuffled = your_list.copy() and then call random.shuffle(shuffled).
random.uniform(a, b) returns a floating-point number N where a <= N <= b. The endpoint b may or may not be included depending on floating-point rounding. In practice, the chance of hitting either exact endpoint is extremely small.
Python uses the Mersenne Twister algorithm as its core pseudo-random number generator. It produces 53-bit precision floats and has a period of 2**19937-1, making it suitable for simulations and general-purpose randomization but not for cryptographic use.
No. The random module is part of the Python standard library and comes pre-installed with every Python distribution. You only need to write import random at the top of your script to start using it.