random-selection
list-operations
algorithm
data-handling
programming-tips

Select 50 items from list at random

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Selecting 50 random items sounds easy, but correctness depends on whether duplicates are allowed and whether selection must be reproducible. The right method changes based on those requirements. Most use cases need sampling without replacement, which is best handled by standard library sampling utilities.

Sampling Without Replacement

If each chosen item must be unique, use random.sample.

python
1import random
2
3items = list(range(1000))
4subset = random.sample(items, 50)
5
6print(len(subset))
7print(len(set(subset)))

This guarantees 50 unique picks, assuming source list has at least 50 elements.

Reproducible Results with Seeds

For tests and experiments, deterministic sampling is useful.

python
1import random
2
3rng = random.Random(42)
4items = ["a", "b", "c", "d", "e", "f"]
5print(rng.sample(items, 3))

Using a local Random instance avoids global random state side effects.

Sampling With Replacement

If duplicates are allowed, use random.choices.

python
1import random
2
3items = ["red", "green", "blue"]
4picks = random.choices(items, k=50)
5print(picks[:10])

This is different from sample and should be chosen intentionally.

Handling Small Lists Safely

random.sample raises ValueError when sample size exceeds input size. Add explicit checks for robust behavior.

python
1import random
2
3def pick_items(items, k=50):
4    if k < 0:
5        raise ValueError("k must be non-negative")
6    if k > len(items):
7        raise ValueError("k exceeds list length for unique sampling")
8    return random.sample(items, k)

This makes failure mode clear for callers.

Large Dataset Considerations

For very large iterables that do not fit in memory, consider reservoir sampling. It selects k random elements from a stream in one pass.

python
1import random
2
3def reservoir_sample(iterable, k):
4    sample = []
5    for i, item in enumerate(iterable):
6        if i < k:
7            sample.append(item)
8        else:
9            j = random.randint(0, i)
10            if j < k:
11                sample[j] = item
12    return sample
13
14stream = range(1_000_000)
15print(len(reservoir_sample(stream, 50)))

Use this when data arrives incrementally.

Weighted Random Selection

If some items should be more likely, use weighted sampling with replacement.

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

For weighted sampling without replacement, use dedicated libraries or custom algorithms.

Cryptographic vs Statistical Randomness

random module is designed for simulation and general-purpose sampling, not security-sensitive choices. If item selection controls tokens, vouchers, or anything adversarial, use secrets and redesign for uniqueness guarantees.

python
1import secrets
2
3def secure_choice(items):
4    if not items:
5        raise ValueError("items cannot be empty")
6    idx = secrets.randbelow(len(items))
7    return items[idx]
8
9items = ["u1", "u2", "u3", "u4"]
10print(secure_choice(items))

For exactly 50 unique secure picks, shuffle with a secure random strategy or use a vetted crypto library that supports secure sampling without replacement.

Avoid Bias from Manual Index Math

Developers sometimes write int(random.random() * n) and accidentally introduce subtle bias when converting floating-point values. Library sampling methods avoid these pitfalls and handle edge cases better.

python
1import random
2
3def bad_pick(items):
4    # Works often, but avoid this style for production selection code.
5    return items[int(random.random() * len(items))]
6
7def good_pick(items):
8    return random.choice(items)

Use high-level APIs first, then optimize only when profiling proves it necessary.

Testing Random Selection Logic

For random code, test invariants rather than exact values unless seeded:

  • result size equals expected k
  • uniqueness constraints hold when required
  • selected items are members of source set

With fixed seed, snapshot tests can verify deterministic behavior.

Common Pitfalls

  • Using choices when unique selection is required.
  • Forgetting to check list length before sample.
  • Relying on global random seed in large applications.
  • Testing exact random output without deterministic seed.
  • Ignoring stream-size constraints in large data workflows.

Summary

  • Use random.sample for unique random selection.
  • Use random.choices when duplicates are acceptable.
  • Add explicit checks for sample-size constraints.
  • Use local seeded RNG for reproducible behavior.
  • For large streams, use reservoir sampling to keep memory bounded.

Related reading
Course
Intermediate
27 lessons
15 hours
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 course
Track 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.

Practice algorithms

All Rights Reserved.