itertools.combinations in Python: Choose Unique Groups

Quick answer: itertools.combinations yields r-length selections of an iterable without replacement. It is lazy and preserves input-position order, but the number of possible results can still grow combinatorially, so choose r and consumption strategy carefully.

Python Pool infographic showing itertools combinations selecting unique r-length groups without replacement and consuming them lazily
itertools.combinations yields r-length selections in input order without replacement; the iterator is lazy, but consuming all results can still be large.

itertools.combinations() returns fixed-length selections from an iterable. Each result is a tuple, order inside the input is preserved, and the same input position is not reused within one combination.

Use it when order does not matter. For example, choosing two team members from a group is a combination problem because ("Ana", "Bo") and ("Bo", "Ana") represent the same pair.

The official Python itertools.combinations documentation defines the function and its result order. The official combinations_with_replacement documentation covers the related form that can reuse input positions.

Create Basic Combinations

Pass an iterable and the desired length r. Convert the iterator to a list only when the result is small enough to hold in memory.

from itertools import combinations

letters = ["A", "B", "C"]
pairs = list(combinations(letters, 2))

print(pairs)

The output contains ("A", "B"), ("A", "C"), and ("B", "C"). It does not include reversed duplicates.

The original input order controls the tuple order and the order in which combinations are produced.

Choose Different Lengths

The second argument controls how many items appear in each tuple.

from itertools import combinations

items = ["red", "green", "blue", "black"]

for size in [2, 3]:
    print(size, list(combinations(items, size)))

A size of two creates pairs. A size of three creates triples. If r is larger than the input length, the iterator produces no results.

This makes the function useful for menus, feature selection, test cases, pairing tasks, and any workflow that needs all unordered selections of a fixed size.

Allow Repeated Items

Use combinations_with_replacement() when the same input item can appear more than once in a result.

from itertools import combinations_with_replacement

scores = [1, 2, 3]

choices = list(combinations_with_replacement(scores, 2))

print(choices)

This includes pairs such as (1, 1) and (2, 2), which normal combinations() would not produce from a single input position.

Use the replacement form for problems such as repeated choices, dice-like outcomes where order is ignored, or selecting categories where the same category can be chosen more than once.

Python Pool infographic showing input positions, r, unique groups, and input order
Combination selection: Input positions, r, unique groups, and input order.

Count Results Before Building Them

The number of combinations grows quickly. Use math.comb() to estimate the result count before materializing a large list.

from itertools import combinations
from math import comb

people = range(30)
group_size = 4

print(comb(len(people), group_size))

first_group = next(combinations(people, group_size))
print(first_group)

For 30 choose 4, the count is already large. Converting the whole iterator to a list may waste memory when you only need to loop over results.

Prefer streaming with a for loop when the output could be large.

Filter Combination Results

Often you generate combinations and then keep only those that satisfy a condition.

from itertools import combinations

numbers = [2, 4, 5, 8, 11]

for pair in combinations(numbers, 2):
    if sum(pair) >= 13:
        print(pair)

This keeps the code readable: combinations() handles selection, and the if statement handles the business rule.

For expensive checks, stop early whenever possible. Combination counts can grow faster than expected.

Python Pool infographic showing iterator output, partial consumption, and memory
Lazy combinations: Iterator output, partial consumption, and memory.

Preview Large Iterators

Use islice() to inspect only the first few results without building the whole sequence.

from itertools import combinations, islice

labels = [f"item-{index}" for index in range(10)]

preview = list(islice(combinations(labels, 3), 5))

print(preview)

This is useful in notebooks, debug output, and tests where the complete result would be too large to display.

Compare Related itertools Tools

combinations(), permutations(), and product() answer different questions. Choose the tool based on whether order matters and whether items can be reused.

Use combinations() when order does not matter and each input position can appear at most once. Use permutations() when order matters. Use product() when choosing one item from each input collection or when repeated positions are part of the problem.

A common mistake is to use permutations and then remove duplicates later. That does extra work and makes the intent less clear. If reversed pairs mean the same thing, start with combinations.

Another mistake is assuming equal values are collapsed. combinations() works by input position, not by unique value. If the input contains duplicate values, the output can contain duplicate-looking tuples. Deduplicate the input first when unique values are required.

For large data, avoid wrapping the result in list() during normal processing. A lazy iterator lets you process one tuple at a time and stop early when enough results have been found.

Before using the function, decide three things: the selection size, whether repeated positions are allowed, and whether order changes the meaning. Those answers identify the right itertools helper and prevent accidental extra work. Combinations ignore order, while Python Permutations With itertools generates ordered arrangements and explains repeated inputs and result counts.

The practical rule is to use combinations() for unordered selections without replacement, combinations_with_replacement() when reuse is allowed, and math.comb() when you need the count before deciding whether to build results.

Keep large combination sets lazy whenever possible. Iterating over the generator is usually better than creating a massive list.

Understand Positions

Combinations select distinct input positions and do not repeat a position within one result. Equal values at different positions can therefore appear in separate combinations.

Python Pool infographic estimating n choose r for zero, small, and large inputs
Combination count: Python Pool infographic estimating n choose r for zero, small, and large inputs.

Choose r

When r is zero, the iterator yields one empty tuple; when r is larger than the input length, it yields nothing. Make that boundary part of the contract.

Use Lazy Consumption

The iterator avoids allocating every result at once. Do not convert it to a list unless the result count and memory budget are known.

Python Pool infographic comparing combinations with replacement, permutations, and product
Related iterators: Combinations with replacement, permutations, and product.

Estimate The Count

For n inputs and r selected positions, the count is n choose r. Estimate it before collecting, sending, or displaying all results.

Compare Related Tools

Use combinations_with_replacement when repeated values are allowed, permutations when order matters, and product for Cartesian choices.

Test Ordering And Values

Test empty and short inputs, r=0, r=1, r=n, r>n, duplicate values, generator inputs, ordering, and partial consumption.

Use the official itertools combinations documentation. Related Python Pool references include lists and testing.

For related sequence workflows, compare list materialization, iterator tests, and count mappings before consuming combinations.

Frequently Asked Questions

What does itertools.combinations do?

It yields subsequences of a chosen length r from the input iterable without repeating positions.

Are combinations ordered?

The output follows the input order of positions, and each combination is emitted in lexicographic order relative to that input.

How many combinations are generated?

For n input items and r selected positions, the count is n choose r when 0 <= r <= n.

Does combinations return a list?

No. It returns an iterator, so values are generated lazily until consumed or converted into a collection.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted