# Python Itertools Combinations

## Table of Contents

## What?

This is a brief note on the python itertools.combinations function.

```
from itertools import combinations
```

To make sure it's behaving the way I think it will I'll also use some other built-ins.

```
from itertools import count
from math import factorial
from math import comb as n_choose_k
```

## Okay, but what?

The `combinations`

function takes two arguments:

- iterable: the source that you want to make combinations from
- r: the length of the sequences you want to make

It returns all the r-length subsequences in the iterable (combinations).

### A Count Function

The number of combinations of length *k* for a sequence of length *n* is the Binomial Coefficient.

I originally implemented a function for this but it turns out it got added to python as of 3.8 (number-theoretic functions). Here's my translation for reference. The calculation is actually really fast so you don't gain a lot from these toy problems using the standard library, but since it's there, why not?

```
def n_choose_k_one(n: int, k: int) -> int:
"""The Binomial Coefficient
Args:
n: the length of the source set
k: the length of the combinations
Returns:
the number of combinations in the sequence
"""
return factorial(n) / (factorial(k) * factorial(n - k))
```

### Example One

This is given as an example in the documentation.

```
EXPECTEDS = "AB AC AD BC BD CD".split()
SOURCE = "ABCD"
k = 2
for combination, expected, total in zip(combinations(iterable=SOURCE, r=k), EXPECTEDS, count(start=1)):
print(f" - {combination}")
assert "".join(combination) == expected
n = len(SOURCE)
assert total == n_choose_k(n, k)
```

- ('A', 'B') - ('A', 'C') - ('A', 'D') - ('B', 'C') - ('B', 'D') - ('C', 'D')

Note that it treated the string as a sequence and returns a tuple, not a sub-string. Also note that it doesn't swap orders, so "D" is never a first entry, for instance.

### Example Two

This one is also from the documentation.

```
SOURCE = list(range(4))
n = len(SOURCE)
EXPECTEDS = [(0, 1, 2),
(0, 1, 3),
(0, 2, 3),
(1, 2, 3)]
k = 3
for combination, expected, total in zip(combinations(SOURCE, k), EXPECTEDS, count(start=1)):
print(combination)
assert combination == expected
assert total == n_choose_k(n, k)
```

(0, 1, 2) (0, 1, 3) (0, 2, 3) (1, 2, 3)