How to Do Random Assignment in Python for A/B Tests
Assign each item to a binary group (0 or 1) with uniform probability using a small reusable function, optionally weighted, for A/B testing mocks.
Python code
18 linesimport random
def random_assignment_uniform_mock(items, weights=None):
"""Assign each item to a group (0 or 1) with uniform probability."""
if weights is None:
# Default: each item independently gets 0 or 1 with 50% probability
return [random.randint(0, 1) for _ in items]
# Optional weighted version: choose group based on provided weights
return [random.choices([0, 1], weights=w, k=1)[0] for w in weights]
if __name__ == "__main__":
items = ["A", "B", "C", "D"]
# Uniform mock: each item assigned to 0 or 1 with equal probability
assignment = random_assignment_uniform_mock(items)
print("Items:", items)
print("Assignment:", assignment)
print("Group 0:", [x for x, a in zip(items, assignment) if a == 0])
print("Group 1:", [x for x, a in zip(items, assignment) if a == 1])
Output
Items: ['A', 'B', 'C', 'D']
Assignment: [0, 1, 0, 1]
Group 0: ['A', 'C']
Group 1: ['B', 'D']
How it works
The function uses random.randint(0, 1) to return 0 or 1 with equal probability regardless of the actual item content, enabling a simple uniform bucket assignment. For weighted control, random.choices picks according to the provided weights per item, which can model non-50/50 splits. Because each call is independent, the function mimics a Bernoulli trial per user, which is the base for many A/B test bucketing strategies.
Common mistakes
- Using `random.random() < 0.5` without caching the seed can produce different results across runs; set `random.seed()` for reproducibility in tests.
- Not checking that the length of `weights` matches the number of items when using the weighted branch, causing a `ValueError`.
- Confusing this mock with deterministic assignment; for stable groups, use hash-based bucketing with a fixed salt.
- Forgetting to reset the random seed in multi-test environments, leading to flaky expectations.
Variations
- Use `random.SystemRandom` for cryptographically secure assignment in security-sensitive contexts.
- Implement a hash-based assignment: `hash(user_id + salt) % 2` instead of true randomness.
Real-world use cases
- Mocking a user bucketing function in unit tests to simulate A/B test enrollment with controlled randomness.
- Creating a quick Python script to split a list of customer IDs into control and treatment groups for email campaign experiments.
- Simulating a feature flag rollout where each incoming request is randomly assigned to the new or old version.
Sponsored
More from A/B testing & experimentation
Keep learning
Related tutorials and quizzes for this topic.