python › random.seed() in Python
phoolchandra · Oct 23, 2026 · Published
Games, OTP generators, lucky draws, shuffling a playlist, splitting data for machine learning — all use random numbers. But what if you need the same "random" numbers every time you run your program, for testing or for reproducible ML results? That is exactly what random.seed() does. In this blog you will understand how random numbers really work in Python and why the seed is so important.
Watch the video first, then use this blog as your notes. Every section has runnable examples, and at the end you will find a "Predict the Output" quiz, practice challenges, a self-check list, interview questions and a quick summary.
How to use this blog: Open the Python shell (type python in your terminal) or any online Python editor and type every example yourself. Change the values, break the code and see what happens — that is how concepts really stick.
import random
print(random.random()) # float in [0.0, 1.0)
print(random.randint(1, 6)) # int from 1 to 6 (both included) - a dice!
print(random.randrange(0, 10, 2)) # 0, 2, 4, 6 or 8
print(random.uniform(1, 10)) # float between 1 and 10
print(random.choice(["red", "green", "blue"])) # one random item
print(random.choices([1, 2, 3], k=5)) # 5 items, repeats allowed
print(random.sample(range(1, 50), 6)) # 6 unique items (lottery!)
cards = [1, 2, 3, 4, 5]
random.shuffle(cards) # shuffles the list in place
print(cards)| Function | Returns | Example use |
|---|---|---|
| random() | Float in [0, 1) | Probabilities |
| randint(a, b) | Int from a to b (inclusive) | Dice, OTP digits |
| randrange(start, stop, step) | Int from range (stop excluded) | Random even number |
| uniform(a, b) | Float between a and b | Random temperature |
| choice(seq) | One item | Pick a winner |
| choices(seq, k=n) | n items with replacement | Simulations |
| sample(seq, k) | k unique items | Lottery numbers |
| shuffle(list) | None (shuffles in place) | Shuffle a deck |
| seed(x) | None (sets the starting point) | Reproducible results |
Run the code above twice — you get different output each time. Now let's see why.
No! Computers are deterministic machines. Python uses a Pseudo-Random Number Generator (PRNG) called the Mersenne Twister. It produces a long sequence of numbers that looks random, using a mathematical formula.
seed ---> [ Mersenne Twister formula ] ---> n1, n2, n3, n4, ...
(starting value) (looks random, but fully
decided by the seed)The seed is the starting value of this formula. Same seed → same sequence of numbers, every single time. If you do not set a seed, Python uses the current system time / OS randomness, so you get different numbers each run.
Analogy: Think of the PRNG as a huge book of random-looking numbers. The seed is the page number you start reading from. Open the same page and you read the same numbers.
import random
random.seed(42)
print(random.randint(1, 100), random.randint(1, 100), random.randint(1, 100))
# 82 15 4
random.seed(42) # reset to the same starting point
print(random.randint(1, 100), random.randint(1, 100), random.randint(1, 100))
# 82 15 4 <-- exactly the same!Try it: run this program 10 times — the output never changes. Remove the seed line and it changes every time.
random.seed(42)
print(random.random()) # 0.6394267984578837
random.seed(42)
print([random.randint(1, 6) for _ in range(5)]) # [6, 1, 1, 6, 3]
random.seed(1)
deck = [1, 2, 3, 4, 5]
random.shuffle(deck)
print(deck) # [3, 4, 5, 1, 2]Note: The exact numbers shown here come from CPython 3. They are guaranteed to be the same every time on the same Python version, but may differ between very different Python versions.
random.seed(a=None, version=2)| Parameter | Meaning |
|---|---|
| a | The seed value: an int, float, str, bytes or bytearray. None (default) uses system time / OS randomness. |
| version | How str/bytes seeds are converted (default 2). You almost never change this. |
random.seed(100) # int seed (most common)
random.seed("coding") # string seeds also work
random.seed() # back to unpredictable randomness| Use case | Why the seed helps |
|---|---|
| Debugging | A bug that appears with "random" data can be reproduced exactly |
| Testing | Unit tests get predictable results and do not fail randomly |
| Machine learning | Same train/test split and same model initialisation → results can be reproduced and compared |
| Scientific simulations | Other researchers can repeat your experiment |
| Games | Same seed → same generated world (like Minecraft world seeds!) |
| Teaching / tutorials | Students see exactly the same output as the teacher |
# Machine learning example (scikit-learn)
from sklearn.model_selection import train_test_split
X = list(range(10))
y = [0, 1] * 5
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42 # random_state = the seed
)
# Same split every time you run itIn data science you will also see np.random.seed(42) for NumPy and torch.manual_seed(42) for PyTorch — the same idea.
random.seed() changes the global generator used by every part of your program. For cleaner code, create your own generator object:
import random
gen = random.Random(42) # its own seed, does not affect the global one
print(gen.randint(1, 100)) # 82
print(random.randint(1, 100)) # unaffected by genBecause the sequence is predictable once the seed is known, the random module is not secure. For passwords, tokens and OTPs use the secrets module:
import secrets
otp = "".join(secrets.choice("0123456789") for _ in range(6))
token = secrets.token_hex(16)
print(otp, token)A teacher wants each student to get the questions in a different order — but the same student must always get the same order. Use the roll number as the seed!
import random
questions = ["Q1: Lists", "Q2: Loops", "Q3: Functions", "Q4: OOP", "Q5: Strings"]
def paper_for(roll_number):
rng = random.Random(roll_number) # seed = roll number
paper = questions[:] # copy, don't change the original
rng.shuffle(paper)
return paper
print(paper_for(101))
print(paper_for(102))
print(paper_for(101)) # identical to the first line - reproducible!| Mistake | What happens | Fix |
|---|---|---|
| Calling random.seed(42) inside a loop before every random call | You get the same number every time | Seed once, at the start of the program |
| Forgetting import random | NameError | Import the module first |
| Thinking randint(1, 10) excludes 10 | Off-by-one bugs | randint includes both ends; randrange excludes stop |
| Using random for passwords | Predictable secrets | Use the secrets module |
| Assigning x = random.shuffle(l) | x is None | shuffle works in place; just use l |
Don't run the code yet! Write your answers in a notebook, then check the Answers section at the end of this blog.
Q1. Will both lines print the same number?
import random
random.seed(5); a = random.randint(1, 10)
random.seed(5); b = random.randint(1, 10)
print(a == b)Q2. What is the output?
import random
l = [1, 2, 3]
print(random.shuffle(l))Q3. Can random.randint(1, 6) return 6?
Q4. Can random.randrange(1, 6) return 6?
Q5. What happens?
import random
for i in range(3):
random.seed(10)
print(random.randint(1, 100), end=" ")Q6. Which algorithm does Python's random module use?
Q7. Which module should you use to generate a secure OTP?
Solve these from easy to tricky:
Solutions for challenges 2, 4 and 5 are in the Answers section.
Tick off each skill once you are confident:
Q: What does random.seed() do?
It initialises the pseudo-random number generator so that the sequence of random numbers becomes reproducible.
Q: What happens if you do not set a seed?
Python seeds the generator from the operating system's randomness or the current time, so results differ on each run.
Q: Why is the seed 42 used so often?
Only by convention — a reference to "The Hitchhiker's Guide to the Galaxy". Any number works.
Q: What is random_state in scikit-learn?
The seed used by scikit-learn functions to make results such as train/test splits reproducible.
Q: Is Python's random truly random?
No, it is pseudo-random (deterministic). For cryptographic security use the secrets module or os.urandom.
| Concept | Syntax / Key point |
|---|---|
| Set seed | random.seed(42) |
| Random int | random.randint(1, 6) |
| Random float | random.random() |
| Pick one | random.choice(seq) |
| Pick k unique | random.sample(seq, k) |
| Shuffle | random.shuffle(lst) |
| Own generator | random.Random(42) |
| Secure token | secrets.token_hex(16) |
# Challenge 2
import random
names = ["Aman", "Riya", "Karan", "Neha", "Ravi", "Sana", "Ali", "Meera", "Dev", "Isha"]
print(random.sample(names, 3))
# Challenge 4
random.seed(1)
tosses = [random.choice(["H", "T"]) for _ in range(1000)]
print("Heads:", tosses.count("H"), "Tails:", tosses.count("T"))
# Challenge 5
import secrets
import string
chars = string.ascii_letters + string.digits
password = "".join(secrets.choice(chars) for _ in range(8))
print(password)You now know how Python generates random numbers and how random.seed() makes them reproducible — a skill you will use constantly in testing, data science and machine learning. Next, continue your OOP journey with Encapsulation in Python.
If this blog helped you, watch the full video above, subscribe to the channel and share it with a friend who is learning Python. Happy coding!