Computing the Kronecker product over a tensor chain
Assuming M is non-negative you can make it clear when J and R are returned and remove some of the nested if-else's.
Since if i+1 ==m only evaluates as true if m &lt;= M you could check that and use different for loops if it's true/false to make things slightly faster but I think that would decrease readability for not much gain
def make_rotate_target(m, M, J, R):
    if M == 0:
        return J

    if M == 1:
        return R

    out = J
    for i in range(1, M):
        if i + 1 == m:
            out = np.kron(out, R)
        else:
            out = np.kron(out, J)

    return out