itertools.combinations() in Python 2026 with Efficient Code
itertools.combinations() is the standard and most efficient way to generate all possible combinations of elements from an iterable. In 2026, it remains one of the most valuable tools in the Python standard library for combinatorial tasks, data analysis, and algorithm development.
This March 15, 2026 guide covers everything you need to know about using itertools.combinations() effectively.
TL;DR — Key Takeaways 2026
combinations(iterable, r)returns all possible r-length combinations- It generates combinations in lexicographic sort order
- Returns an iterator — very memory efficient
- Much faster and cleaner than writing nested loops
- Works with any iterable (lists, strings, tuples, etc.)
1. Basic Usage
from itertools import combinations
team = ["Alice", "Bob", "Carol", "Dave"]
# All possible pairs (r=2)
pairs = list(combinations(team, 2))
print(pairs)
# [('Alice', 'Bob'), ('Alice', 'Carol'), ('Alice', 'Dave'), ('Bob', 'Carol'), ('Bob', 'Dave'), ('Carol', 'Dave')]
# All possible groups of 3
groups = list(combinations(team, 3))
2. Real-World Efficient Patterns in 2026
# 1. Choosing toppings
toppings = ["cheese", "pepperoni", "mushroom", "onion", "sausage"]
for combo in combinations(toppings, 3):
print("Pizza with:", ", ".join(combo))
# 2. With indices
for i, combo in enumerate(combinations(team, 2), start=1):
print(f"Combination {i}: {combo}")
# 3. Converting to list of strings
pairs_str = [f"{a}-{b}" for a, b in combinations(team, 2)]
# 4. Large combinations with lazy iteration
large_set = range(20)
for combo in combinations(large_set, 5):
# Process each combination without loading all into memory
pass
3. Performance Comparison 2026
| Method | Readability | Performance | Memory Usage |
|---|---|---|---|
| Nested Loops | Poor | Slow | High |
itertools.combinations | Excellent | Very Fast | Low (iterator) |
4. Best Practices with itertools.combinations() in 2026
- Always prefer
combinations()over manual nested loops - Use
enumerate()when you need indices - Keep it lazy — only convert to list when necessary
- Combine with
Counteror other tools for powerful data analysis - Use with large datasets carefully — combinations grow factorially
combinations, permutations and product
combinations(items, r) returns unique groups where order does not matter, so (a, b) and (b, a) count once. permutations(items, r) treats different orders as different results. product(items, repeat=r) allows an item to appear more than once.
combinations_with_replacement sits between them: order does not matter, but items may repeat. Choosing the right function matters because the output sizes differ a lot.
All four are lazy iterators, so you can loop over very large result sets without storing them.
Worked Example: Comparing the Four Functions
We count the results of each function for the same three items.
from itertools import combinations, combinations_with_replacement, permutations, product
items = ["A", "B", "C"]
print(list(combinations(items, 2)))
print(len(list(permutations(items, 2))))
print(len(list(combinations_with_replacement(items, 2))))
print(len(list(product(items, repeat=2))))
budget = 30
prices = {"pen": 5, "book": 18, "lamp": 25, "mug": 9}
print([pair for pair in combinations(prices, 2) if prices[pair[0]] + prices[pair[1]] <= budget])
For three items, there are 3 combinations, 6 permutations, 6 combinations with replacement and 9 products. The last line finds every pair of products that fits a budget of 30.
Practical Tips
The size of each result grows quickly: for n items and groups of r, there are n!/(r!(n-r)!) combinations but n!/(n-r)! permutations. Use math.comb and math.perm to check the counts before generating anything.
When searching for the best combination, keep only the current best result while looping instead of storing every candidate. This keeps the search memory-friendly even when millions of combinations are checked.
Sorting the input first makes the output order predictable, which helps when tests compare results. Both functions emit tuples in the order of the input, so a sorted input gives sorted, reproducible results that are easy to review.
If only the count is needed, use math.comb or math.perm and skip generation entirely, which is instant even for very large inputs.
Common Mistakes
- Using permutations when order does not matter.
- Forgetting that items in a combination keep input order.
- Materialising very large outputs.
- Passing a dictionary and expecting values instead of keys.
Quick Summary
- combinations ignore order.
- permutations respect order.
- product allows repeats.
- All are lazy iterators.
Conclusion — itertools.combinations() in 2026
itertools.combinations() is the clean, efficient, and Pythonic way to generate combinations. In 2026, replacing manual nested loops with combinations() is considered a basic best practice that improves both performance and code maintainability.
Next steps:
- Replace all manual combination loops in your codebase with
itertools.combinations()