Найти индекс заданной комбинации (натуральных чисел) среди возвращенных модулем Python `itertools`

Учитывая комбинациюk из первыхn натуральные числа, по какой-то причине мне нужно найти положение такой комбинации среди возвращенныхitertools.combination(range(1,n),k) (причина в том, что таким образом я могу использоватьlist вместоdict для доступа к значениям, связанным с каждой комбинацией, зная комбинацию).

посколькуitertools дает его комбинации в регулярном порядке, это можно сделать (и я также нашел аккуратный алгоритм), но я ищу еще более быстрый / естественный способ, который я мог бы игнорировать.

Кстати вот мое решение:

def find_idx(comb,n):
    k=len(comb)
    idx=0
    last_c=0
    for c in comb:
        #idx+=sum(nck(n-2-x,k-1) for x in range(c-last_c-1)) # a little faster without nck caching
        idx+=nck(n-1,k)-nck(n-c+last_c,k) # more elegant (thanks to Ray), faster with nck caching
        n-=c-last_c
        k-=1
        last_c=c
    return idx

гдеnck возвращаетбиномиальный коэффициент n, k.

Например:

comb=list(itertools.combinations(range(1,14),6))[654] #pick the 654th combination
find_idx(comb,14) # -> 654

И вот эквивалентная, но, возможно, менее вовлеченная версия (на самом деле я вывел предыдущую из следующей). Я рассмотрел целые числа комбинацииc как позиции 1 в двоичной цифре, я построил двоичное дерево при разборе 0/1 и обнаружил регулярную последовательность приращений индекса при разборе:

def find_idx(comb,n):
    k=len(comb)
    b=bin(sum(1<<(x-1) for x in comb))[2:]
    idx=0
    for s in b[::-1]:
        if s=='0':
            idx+=nck(n-2,k-1)
        else:
            k-=1
        n-=1
    return idx

Ответы на вопрос(3)

Ваш ответ на вопрос