Python
Combinations
Mutually Exclusive Sets
List Elements
Algorithms

Find in python combinations of mutually exclusive sets from a list's elements

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python, "combinations of mutually exclusive sets" can mean two different problems. Sometimes the input is already partitioned into groups and you want one choice from each group, and sometimes you have a flat set of items with conflict rules and need only those combinations that avoid incompatible pairs.

When the Input Is Already Grouped

If each sublist is a mutually exclusive group and the rule is "pick one from each group", the problem is a Cartesian product.

python
1from itertools import product
2
3groups = [
4    ["A", "B"],
5    ["C", "D"],
6    ["E", "F"],
7]
8
9result = list(product(*groups))
10print(result)

This returns all valid selections with exactly one choice per group. It is the cleanest answer when the input structure already encodes the exclusivity.

When You Need k Valid Elements from a Flat List

If the input is a flat list and some items cannot appear together, the simplest general solution is to generate combinations of size k and then filter out invalid ones.

python
1from itertools import combinations
2
3items = ["A", "B", "C", "D"]
4conflicts = {
5    "A": {"B"},
6    "B": {"A"},
7    "C": {"D"},
8    "D": {"C"},
9}
10
11
12def is_valid(combo):
13    chosen = set(combo)
14    for item in combo:
15        if chosen & conflicts.get(item, set()):
16            return False
17    return True
18
19
20valid = [combo for combo in combinations(items, 2) if is_valid(combo)]
21print(valid)

This is fine for small inputs and easy to understand. The tradeoff is that it still builds every raw combination before rejecting the invalid ones.

Backtracking Prunes Invalid Branches Earlier

If the search space is larger, backtracking is more efficient because it avoids exploring partial combinations that are already impossible.

python
1items = ["A", "B", "C", "D", "E"]
2conflicts = {
3    "A": {"B"},
4    "B": {"A", "D"},
5    "C": set(),
6    "D": {"B"},
7    "E": set(),
8}
9
10
11def build_valid_combinations(items, conflicts, k):
12    result = []
13
14    def backtrack(start, chosen):
15        if len(chosen) == k:
16            result.append(tuple(chosen))
17            return
18
19        for index in range(start, len(items)):
20            item = items[index]
21            if any(item in conflicts.get(existing, set()) for existing in chosen):
22                continue
23            if any(existing in conflicts.get(item, set()) for existing in chosen):
24                continue
25
26            chosen.append(item)
27            backtrack(index + 1, chosen)
28            chosen.pop()
29
30    backtrack(0, [])
31    return result
32
33
34print(build_valid_combinations(items, conflicts, 3))

This version does less wasted work because it stops immediately when the current partial choice already violates the exclusion rules.

Model the Constraint Carefully

Many bugs come from poor problem definition rather than poor Python code. You need to decide whether:

  • conflicts are symmetric
  • you must choose exactly one item from each group
  • you may skip groups entirely
  • the rule is based on groups or on arbitrary pair conflicts

Those are different problems. It is worth normalizing the conflict data first if symmetry is intended, because later algorithm logic becomes much clearer.

Pick the Simplest Correct Shape

A practical rule is:

  • use itertools.product for one-from-each-group selection
  • use combinations plus filtering for small generic problems
  • use backtracking when pruning invalid partial selections matters

That lets the algorithm follow the data shape instead of forcing all versions of the problem into one pattern.

Common Pitfalls

  • Using combinations when the input is really a grouped selection problem better expressed as a product.
  • Generating all candidates and filtering later even when backtracking would prune early.
  • Forgetting to normalize symmetric conflict rules.
  • Solving "exactly one from each group" as if it were the same as "any valid subset of size k".
  • Encoding the conflict rules unclearly enough that the algorithm becomes harder to verify than the problem.

Summary

  • Mutual-exclusion combination problems come in more than one shape.
  • Use product when the groups are already defined and you need one choice from each.
  • Use combinations plus a validity check for small flat-list cases.
  • Use backtracking when the search space is large enough that pruning helps.
  • Define the exclusivity rule clearly before choosing the algorithm.

Course illustration
Course illustration

All Rights Reserved.