'Return a transversal of the right cosets of self by its subgroup H
using the second method described in [1], Subsection 4.6.7'

def coset_transversal(self, H):

    if (not H.is_subgroup(self)):
        raise ValueError('The    argument    must    be    a    subgroup')
    if (H.order() == 1):
        return self._elements
    self._schreier_sims(base=H.base)
    base = self.base
    base_ordering = _base_ordering(base, self.degree)
    identity = Permutation((self.degree - 1))
    transversals = self.basic_transversals[:]
    for (l, t) in enumerate(transversals):
        transversals[l] = sorted(t.values(), key=(lambda x: base_ordering[(base[l] ^ x)]))
    orbits = H.basic_orbits
    h_stabs = H.basic_stabilizers
    g_stabs = self.basic_stabilizers
    indices = [(x.order() // y.order()) for (x, y) in zip(g_stabs, h_stabs)]
    T = g_stabs[len(h_stabs)]._elements
    t_len = len(T)
    l = (len(h_stabs) - 1)
    while (l > (-1)):
        T_next = []
        for u in transversals[l]:
            if (u == identity):
                continue
            b = base_ordering[(base[l] ^ u)]
            for t in T:
                p = (t * u)
                if all([(base_ordering[(h ^ p)] >= b) for h in orbits[l]]):
                    T_next.append(p)
                if ((t_len + len(T_next)) == indices[l]):
                    break
            if ((t_len + len(T_next)) == indices[l]):
                break
        T += T_next
        t_len += len(T_next)
        l -= 1
    return T
