Random weighted choice
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Random weighted choice means choosing one item at random, but not with equal probability. Each item has a weight, and larger weights make that item more likely to be selected.
The Core Idea
Suppose you have three items with weights 1, 2, and 7. The total weight is 10, so the items are chosen with probabilities 0.1, 0.2, and 0.7.
The standard approach is:
- compute the total weight
- generate a random number between
0and that total - walk through the items until the cumulative weight crosses the random number
That works because each item owns a segment of the total numeric range, and the random number lands inside one of those segments.
Simple Python Implementation
Here is a small implementation that works well for occasional sampling:
This algorithm is easy to understand and is good enough when the list is small or sampling happens infrequently.
Use the Standard Library When Available
In Python, the built-in solution is usually cleaner than writing your own helper. random.choices already supports weights.
This is the best option for most application code because it is short, tested, and easy to read.
Scale Better With Prefix Sums
If you are sampling repeatedly from a fixed set of weights, build cumulative weights once and then use binary search for each draw. That reduces the selection step from a linear scan to logarithmic time.
This is a better design when the item set stays the same and you need many random draws, such as in simulations or recommendation experiments.
Why Weight Validation Matters
Weighted sampling only makes sense when weights are non-negative and the total weight is positive. A zero weight means the item should never be selected. Negative weights usually indicate a bug in the upstream logic.
Adding a validation step prevents silent nonsense:
That is worth doing whenever the weights come from user input, configuration, or a model output that may be malformed.
Performance Notes
For one-off selections, the simple cumulative scan is fine. For many selections from the same distribution, prefix sums plus binary search are better. For very high-throughput systems, there are more advanced structures such as the alias method, but they are usually unnecessary unless sampling speed is a major bottleneck.
The right algorithm depends on whether weights change often. If the weights are updated every draw, rebuilding a sampling structure may cost more than the optimization is worth.
Common Pitfalls
The first mistake is forgetting that weights are relative, not percentages. The values 1, 2, 7 and 10, 20, 70 produce the same distribution.
Another common issue is allowing negative weights or a total weight of zero. In that case, the distribution is undefined and the code should fail fast.
Floating-point edge cases can also appear when weights are extremely small or extremely large. For most application code this is fine, but numerically sensitive systems may need careful scaling or higher-precision arithmetic.
Finally, do not confuse sampling without replacement with weighted choice. The examples here select with replacement. If an item should disappear after selection, you need a different update step.
Summary
- Weighted choice selects items with probability proportional to their weights.
- A cumulative-weight scan is the simplest correct algorithm.
- '
random.choicesis the easiest Python solution for most code.' - Prefix sums plus binary search help when you sample many times from fixed weights.
- Validate weights so negative or all-zero inputs fail clearly.
Related reading
- Randomized algorithm for finding hamiltonian path in a directed graph
- Randomly selecting k different numbers in a range
- Randomness in Artificial Intelligence Machine Learning
- Range Minimum Query On, O1 approach from tree to restricted RMQ
- Randomly Generate Letters According to their Frequency of Use?
- Rasterizing a 2D polygon
- Range Minimum Query On, O1 approach Last steps
- Rank items in an array using Python/NumPy, without sorting array twice

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.