Generate all combinations from multiple lists
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Generating all combinations from multiple lists is the cartesian-product problem. If you have several collections and want one element from each, every possible tuple belongs to the result set. This is simple conceptually, but the implementation details matter once the number of lists grows or the result size becomes very large.
Understand the Cartesian Product
If the input lists are:
[1, 2]['x', 'y']['I', 'II']
then the combinations are:
Each tuple contains one choice from each input list. The order of lists matters because the first position comes from the first list, the second from the second list, and so on.
Use itertools.product in Python
In Python, the most direct and readable solution is itertools.product.
This is the standard library implementation of the cartesian product. It is concise and avoids reimplementing nested loops manually.
If you want a materialized list instead of an iterator:
For small inputs this is convenient. For larger inputs, keeping the result as an iterator is often better.
Build It Recursively When You Need Custom Logic
If you want to filter, transform, or stop early in a custom way, a recursive solution can be helpful.
This structure mirrors the problem definition directly: choose one element from the first list, then recursively choose from the remaining lists.
Understand the Growth of the Result Size
The total number of combinations is the product of the list lengths. If the lengths are a, b, and c, then the result size is a * b * c.
That means the main difficulty is not the loop logic. It is the combinatorial explosion.
For example:
- 3 lists of length 10 give 1,000 combinations.
- 6 lists of length 10 give 1,000,000 combinations.
This is why generator-based approaches are often preferable. They let you process combinations one at a time instead of trying to hold everything in memory.
Handle Empty Lists Deliberately
If any input list is empty, the entire product is empty because no complete tuple can be formed.
That returns an empty list. This behavior is correct, but it is worth calling out because it surprises people when the rest of the lists are non-empty.
Prefer Iteration Over Hardcoded Nested Loops
Manual nested loops work only when the number of lists is fixed in advance. As soon as the list count is dynamic, hardcoded loops become unmaintainable.
That is why recursive generation or library tools such as itertools.product are better. They solve the general problem once instead of rewriting the same logic for three lists, four lists, five lists, and so on.
Common Pitfalls
- Materializing the entire product into memory when an iterator would be sufficient.
- Forgetting that the total result size grows as the product of the list lengths.
- Using hardcoded nested loops for a problem where the number of input lists can vary.
- Expecting non-empty output when one of the input lists is empty.
- Confusing combinations from multiple lists with combinations chosen from one list without replacement.
Summary
- Generating all combinations from multiple lists is the cartesian-product problem.
- In Python,
itertools.productis the clearest standard solution. - Recursive generation is useful when you need custom traversal behavior.
- The real challenge is result-size growth, not syntax.
- Prefer generators when the product may be large and you do not need every tuple in memory at once.

