Python random: Numbers, Choices, and Samples

Updated on: August 20, 2026
Reading time: 5 minutes
Uso do módulo random para gerar valores aleatórios em Python

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 random

The 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 cause IndexError; use choice().
  • Expecting shuffle() to return a list. It modifies the list in place and returns None.
  • Using sample() with a value of k larger than the population.
  • Using random for 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.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Document and inbox representing local email stores with Python mailbox
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python mailbox: Local Email Stores

    Learn Python mailbox to read, create, and migrate Maildir, mbox, and MH stores with locking, flags, message parsing, and safe

    Ler mais

    Tempo de leitura: 5 minutos
    12/08/2026
    Text editor representing formatting with Python textwrap
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python textwrap: Format Text

    Learn Python textwrap to wrap, fill, shorten, indent, and dedent text with controlled width, whitespace, long words, and reusable settings.

    Ler mais

    Tempo de leitura: 4 minutos
    10/08/2026
    Folder and magnifying glass representing file-name filters with Python fnmatch
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python fnmatch: Filter File Names

    Learn Python fnmatch to filter file names with shell wildcards, control case sensitivity, exclude patterns, and distinguish glob from regex.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Monitor with binary data representing compact numeric arrays in Python
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python array: Compact Numeric Data

    Learn Python array for compact numeric storage, binary files, byte order, memory views, and safe buffer interoperability.

    Ler mais

    Tempo de leitura: 6 minutos
    10/08/2026
    Color wheel representing RGB, HSV, and HLS conversions with Python colorsys
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python colorsys: RGB, HSV, and HLS

    Learn Python colorsys to convert colors between RGB, HSV, HLS, and YIQ, generate palettes, and avoid scale and precision mistakes.

    Ler mais

    Tempo de leitura: 5 minutos
    09/08/2026
    Configuration icon representing plist files with Python plistlib
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    plistlib: Read and Write Apple Plist Files

    Learn Python plistlib to read and write XML and binary plist files, validate data, handle dates, bytes, and UIDs safely.

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026