Enumerating all partial permutations of given length in lexicographic order
Here is a simple iterative solution. We maintain two arrays, an output array $L$, and a Boolean array $A$, which keeps track of the elements currently in $L$. We update $A$ as we add and remove elements from $L$.
We initialize $L$ with $0,\ldots,k-1$, which is also our first output. Now we repeatedly try to &quot;increment&quot; $L$. If successful, we output the incremented $L$, and try to increment $L$ again. If unsuccessful, we have gone through all combinations, and can terminate.
In order to increment $L$, we start by trying to increment position $k-1$ (this is the rightmost position). We do so by scanning the array $A$ starting at $L[k-1] + 1$, until we find an element $x$ which is not in $L$. If this search is successful, we replace $L[k-1]$ with $x$. Otherwise, we try to do the same for $L[k-2],\ldots,L[0]$, until successful; if all of these fail, we declare failure (and terminate).
Suppose that we have successfully replaced $L[j]$. If $j = k-1$, we're done. Otherwise, we have to update $L[j+1],\ldots,L[k-1]$, which we do by scanning $A$ starting at $0$, inserting the first $k-j-1$ elements not already in $L$.
Here is a Python implementation:
def gen(n, k): 
    A = [True] * k + [False] * (n-k) 
    L = list(range(k)) 
    yield tuple(L) 
    while True: 
        j = k - 1 
        while j &gt;= 0: 
            A[L[j]] = False 
            t = L[j] + 1 
            while t &lt; n and A[t]: 
                t += 1 
            if t &lt; n: 
                A[t] = True 
                L[j] = t 
                r = 0 
                j += 1 
                while j &lt; k: 
                    while A[r]: 
                        r += 1 
                    A[r] = True 
                    L[j] = r 
                    j += 1 
                yield tuple(L)
                break 
            else: 
                j -= 1 
        if j == -1: 
            break 


An even simpler recursive solution simply iterates over all possible choices of the first element; within these, iterates over all possible choices of the second element; and so on.
Here is a Python implementation:
def gen_rec(n, k, L=[]): 
    if len(L) == k: 
        yield tuple(L) 
    for i in range(n): 
        if i not in L: 
            yield from gen_rec(n, k, L + [i])