(expr, fct)
If a sympy 'Expr' is of the form:

    expr = expr_i1i2...irj*a_i1*a_i2*...*a_ir or expr_0

    where all the a_i are noncommuting symbols in basis and the expr's

    are commuting expressions then

    multilinear_product(expr) = expr_i1i2...ir*fct(a_i1, a_i2, ..., a_ir)

    bilinear_product(expr_0) = expr_0

    where fct() is defined for r <= n the total number of bases
If a sympy 'Expr' is of the form:
If a sympy Expr is of the form :
def multilinear_product(expr, fct):
    """
    If a sympy 'Expr' is of the form:

    expr = expr_i1i2...irj*a_i1*a_i2*...*a_ir or expr_0

    where all the a_i are noncommuting symbols in basis and the expr's

    are commuting expressions then

    multilinear_product(expr) = expr_i1i2...ir*fct(a_i1, a_i2, ..., a_ir)

    bilinear_product(expr_0) = expr_0

    where fct() is defined for r <= n the total number of bases
    """
    if expr.is_commutative:  # no bases in expr
        return expr
    if isinstance(expr, Mul):  # bases in expr
        (coefs, bases) = expr.args_cnc()
        if len(coefs) == 0:  # expr_ij = 1
            coefs = [S.One]
        coef = Mul(*tuple(coefs))
        new_bases = []
        for base in bases:
            if isinstance(base, Pow):
                args = base.args
                new_bases += args[1] * [args[0]]
            else:
                new_bases.append(base)
        return coef * fct(new_bases)
def multilinear_product ( expr , fct ) : if expr . is_commutative : # no bases in expr return expr if isinstance ( expr , Mul ) : # bases in expr ( coefs , bases ) = expr . args_cnc ( ) if len ( coefs ) == 0 : # expr_ij = 1 coefs = [ S . One ] coef = Mul ( * tuple ( coefs ) ) new_bases = [ ] for base in bases : if isinstance ( base , Pow ) : args = base . args new_bases += args [ 1 ] * [ args [ 0 ] ] else : new_bases . append ( base ) return coef * fct ( new_bases )