itertools.combinations() in Python 2026 with Efficient Code

Efficient Code Mar 15, 2026

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 LoopsPoorSlowHigh
itertools.combinationsExcellentVery FastLow (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 Counter or 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()

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices