если n не далеко от r, тогда лучше использовать рекурсивное определение комбинации, так как xC0 == 1 у вас будет всего несколько итераций:
Соответствующее рекурсивное определение здесь:
nCr = (n-1) C (r-1) * n / r
Это может быть легко вычислено с использованием хвостовой рекурсии со следующим списком:
[(n - r, 0), (n - r + 1, 1), (n - r + 2, 2), ..., (n - 1, r - 1), (n, r )]
, который, конечно, легко генерируется в Python (мы пропускаем первую запись, поскольку nC0 = 1) с помощью izip(xrange(n - r + 1, n+1), xrange(1, r+1))
Обратите внимание, что это предполагает, что r <= n, вам нужно проверить это и поменять их местами, если это не так. Также для оптимизации использования, если r <n / 2, то r = n - r. </p>
Теперь нам просто нужно применить шаг рекурсии, используя хвостовую рекурсию с помощью Reduce. Мы начинаем с 1, поскольку nC0 равно 1, а затем умножаем текущее значение на следующую запись из списка, как показано ниже.
from itertools import izip
reduce(lambda x, y: x * y[0] / y[1], izip(xrange(n - r + 1, n+1), xrange(1, r+1)), 1)