Randomness appears in games, simulations, tests, data sampling, raffles, and many everyday scripts. Python includes the random module in its standard library, so you can generate pseudo-random numbers and choose items without installing a package.
This guide explains the functions beginners use most: random(), randint(), randrange(), uniform(), choice(), choices(), sample(), shuffle(), and seed(). You will also learn an essential security rule: use secrets, not random, for passwords, reset tokens, and authentication codes.
If you are still building your foundations, the Python beginner guide and the guide to Python lists will help with the sequences used throughout this tutorial.
What the Python random Module Does
The module provides pseudo-random generators. The results look unpredictable for ordinary programs, but they are produced by a deterministic algorithm. That makes the module fast and useful for games, simulations, demonstrations, and repeatable tests.
Import it once at the top of your script:
import randomThe official Python random documentation lists every available distribution and sequence operation.
Generate a Float with random()
random.random() returns a floating-point number from 0.0 up to, but not including, 1.0.
import random
value = random.random()
print(value)You can scale the result, although specialized functions are usually clearer:
percentage = random.random() * 100
print(f"{percentage:.2f}%")Generate Integers with randint() and randrange()
randint(a, b) includes both endpoints. The following code can return any integer from 1 through 6:
dice_roll = random.randint(1, 6)
print(dice_roll)randrange() follows the same boundaries as range(). Its stop value is excluded, and an optional step can restrict the available values.
number = random.randrange(10) # 0 through 9
multiple_of_five = random.randrange(0, 101, 5)
print(number, multiple_of_five)A practical use is the number guessing game in Python, where randint() creates the secret number.
Generate Decimal Values with uniform()
uniform(a, b) returns a floating-point value between two limits. Because floating-point calculations involve rounding, the upper endpoint may or may not appear.
temperature = random.uniform(18.0, 30.0)
print(f"Simulated temperature: {temperature:.1f}°C")This is useful for simple simulations, randomized test inputs, and sample measurements. It should not be confused with a statistically complete model of a real process.
Choose One Item with choice()
choice() selects one element from a non-empty sequence.
colors = ["red", "green", "blue", "yellow"]
selected = random.choice(colors)
print(selected)If the sequence is empty, Python raises IndexError. Validate data before choosing when the list may be empty.
The Hangman game in Python uses this pattern to choose a secret word.
Choose Several Items: sample() vs. choices()
The difference is replacement:
sample(population, k)selects unique positions without replacement.choices(population, k=k)selects with replacement, so an item may appear more than once.
students = ["Ava", "Noah", "Mia", "Leo", "Zoe"]
team = random.sample(students, k=3)
repeated_draws = random.choices(students, k=5)
print("Team:", team)
print("Draws:", repeated_draws)sample() raises ValueError if k is larger than the population. For large integer populations, sampling from a range is memory-efficient.
Weighted choices
choices() accepts relative weights:
prizes = ["small", "medium", "large"]
weights = [70, 25, 5]
result = random.choices(prizes, weights=weights, k=1)[0]
print(result)The values do not have to add up to 100. They only express relative likelihood.
Shuffle a List in Place
shuffle() changes the original mutable sequence and returns None.
cards = ["A", "K", "Q", "J", "10"]
random.shuffle(cards)
print(cards)To preserve the original sequence, copy it first:
original = [1, 2, 3, 4, 5]
shuffled = original.copy()
random.shuffle(shuffled)
print(original)
print(shuffled)For more tools that work lazily with iterables, see the Python itertools guide.
Use seed() for Repeatable Results
A fixed seed helps reproduce a pseudo-random sequence during teaching, debugging, and tests.
import random
random.seed(42)
print(random.randint(1, 100))
print(random.randint(1, 100))Running the same compatible code with the same seed can reproduce the sequence. Do not use a predictable seed as a security mechanism. A seed is for reproducibility, not secrecy.
Use a separate Random instance
A dedicated generator avoids changing the module-wide state:
generator = random.Random(42)
print(generator.choice(["north", "south", "east", "west"]))
print(generator.random())This pattern is useful in tests because one component can have deterministic random data without affecting another component.
random Is Not for Passwords or Tokens
The default generator is deterministic and unsuitable for cryptographic purposes. Use the standard-library secrets module when unpredictability protects an account or sensitive action.
import secrets
verification_code = secrets.randbelow(900000) + 100000
token = secrets.token_urlsafe(32)
print(verification_code)
print(token)The official Python secrets documentation covers secure choices and token generation. The detailed Python secrets guide explains practical security examples.
Practical Project: Create Balanced Random Groups
The following function shuffles names and distributes them across a chosen number of groups. Group sizes differ by at most one when the division is uneven.
import random
def create_groups(names, number_of_groups, seed=None):
if number_of_groups < 1:
raise ValueError("number_of_groups must be at least 1")
if number_of_groups > len(names):
raise ValueError("there cannot be more groups than names")
generator = random.Random(seed)
shuffled_names = list(names)
generator.shuffle(shuffled_names)
groups = [[] for _ in range(number_of_groups)]
for index, name in enumerate(shuffled_names):
groups[index % number_of_groups].append(name)
return groups
participants = [
"Ava", "Noah", "Mia", "Leo",
"Zoe", "Liam", "Ivy", "Eli",
]
for number, group in enumerate(
create_groups(participants, 3, seed=7),
start=1,
):
print(f"Group {number}: {', '.join(group)}")This project combines copying, shuffling, list comprehensions, modulo arithmetic, and enumerate(). The companion Python enumerate guide explains the numbered loop in detail.
Common Mistakes
- Using
randint(0, len(items))as a list index. The final value can equal the length and causeIndexError; usechoice(). - Expecting
shuffle()to return a list. It modifies the list in place and returnsNone. - Using
sample()with a value ofklarger than the population. - Using
randomfor passwords, reset links, API keys, or session tokens. - Setting a fixed seed in production and accidentally making every run identical.
- Assuming random-looking output is automatically statistically appropriate for a real-world model.
Frequently Asked Questions
Do I need to install random?
No. It is part of Python’s standard library.
Does randint() include the upper limit?
Yes. randint(1, 6) can return both 1 and 6.
How do I choose unique winners?
Use random.sample(participants, k=number_of_winners).
How do I choose with repeated results allowed?
Use random.choices(population, k=amount).
Why use a seed?
A seed is useful when you need to reproduce a sequence for debugging, examples, or tests.
What should I use for secure tokens?
Use secrets.token_urlsafe(), secrets.token_hex(), or another function from secrets.
Conclusion
The Python random module provides a compact toolkit for ordinary randomness. Use randint() and uniform() for numbers, choice() for one element, sample() for unique selections, choices() for repeated or weighted selections, and shuffle() to reorder a list.
Use fixed seeds deliberately and only where repeatability helps. For every security-sensitive value, switch to secrets. That single distinction prevents one of the most common mistakes beginners make with random data.






