Python
Weighted Random
Duplicate Question
Programming
Randomization

Python Weighted Random

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Weighted random selection means some outcomes should be more likely than others. In Python, the standard answer is usually random.choices, but the full solution also depends on whether you need sampling with replacement, reproducible results, or cryptographic randomness.

The Standard Tool: random.choices

For most application code, random.choices is the simplest way to draw weighted outcomes.

python
1import random
2
3items = ["bronze", "silver", "gold"]
4weights = [70, 25, 5]
5
6rng = random.Random(42)
7draws = rng.choices(items, weights=weights, k=10)
8print(draws)

This chooses ten results, where bronze is most likely and gold is least likely.

The weights are relative. They do not need to add up to 100 or to 1.0.

Understand Sampling With Replacement

random.choices samples with replacement. That means the same item can appear multiple times.

python
1import random
2
3items = ["A", "B", "C"]
4weights = [1, 1, 10]
5
6print(random.choices(items, weights=weights, k=5))

Repeated values are normal here. If the requirement is "draw multiple unique items with weights," that is a different problem.

Validate Inputs

Weighted selection only makes sense if the inputs are valid. A small validation helper prevents hard-to-debug bias or runtime errors.

python
1def validate_weighted_input(items, weights):
2    if len(items) != len(weights):
3        raise ValueError("items and weights must have the same length")
4    if not items:
5        raise ValueError("items cannot be empty")
6    if any(w < 0 for w in weights):
7        raise ValueError("weights must be non-negative")
8    if sum(weights) <= 0:
9        raise ValueError("sum of weights must be positive")

Negative weights and all-zero weights should be treated as invalid input, not as special cases to ignore.

Reproducibility With a Dedicated Random Generator

If you are writing tests, simulations, or data pipelines, avoid depending on the process-wide global random state. Create a Random instance with a seed.

python
1import random
2
3rng = random.Random(12345)
4items = ["red", "green", "blue"]
5weights = [5, 3, 2]
6
7print(rng.choices(items, weights=weights, k=4))
8print(rng.choices(items, weights=weights, k=4))

Using a dedicated generator makes runs easier to reproduce and isolates your code from other random operations happening elsewhere in the process.

Repeated Sampling Can Use Cumulative Weights

Python also supports cumulative weights, which are useful if you already have them precomputed.

python
1import random
2
3items = ["small", "medium", "large"]
4cumulative_weights = [50, 90, 100]
5
6print(random.choices(items, cum_weights=cumulative_weights, k=6))

This can be convenient when the cumulative distribution is already available from upstream code.

Without Replacement Is Different

Python's built-in random.sample does not support weights. If you need weighted sampling without replacement, you need a custom algorithm or a third-party library such as NumPy, depending on the scale and constraints of the task.

For many basic applications, though, weighted sampling with replacement is exactly what is intended.

Security-Sensitive Selection

Do not use the random module for security-sensitive behavior such as token selection or secret generation. Python's random module is designed for simulation and general-purpose randomness, not for cryptographic security.

If security matters, use the secrets module, though it does not provide weighted selection directly.

Common Pitfalls

The biggest pitfall is forgetting that random.choices samples with replacement. If duplicates in the result seem surprising, the underlying requirement was probably weighted sampling without replacement.

Another issue is assuming weights must be normalized first. They do not. Relative magnitudes are what matter.

Developers also forget to validate inputs, especially when weights come from configuration or external data. A negative or mismatched weight list should fail fast.

Finally, do not use random for security-sensitive logic. Reproducible pseudo-randomness is useful, but it is not cryptographic randomness.

Summary

  • Use random.choices for standard weighted random selection in Python.
  • Weights are relative and do not need to sum to a fixed total.
  • 'random.choices samples with replacement, so duplicates are expected.'
  • Use a seeded Random instance when reproducibility matters.
  • Use a different approach if you need weighted sampling without replacement or cryptographic security.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.