from functools import reduce
from operator import mul


def nth_product(index, *args):
    """Equivalent to ``list(product(*args))[index]``.

    The products of **args* can be ordered lexicographically. 
    :func:`nth_product` computes the product at sort position *index* without 
    computing the previous products.
    
    """
    pools = list(map(tuple, reversed(args)))
    ns = list(map(len, pools))
    
    c = reduce(mul, ns)
    
    if index < 0:
        index += c
    
    if (index < 0) or (index >= c):
        raise IndexError
    
    result = []
    for pool, n in zip(pools, ns):
        result.append(pool[index % n])
        index //= n
    
    return tuple(reversed(result))