def distinct_permutations ( iterable ) : def make_new_permutations ( permutations , e ) : """Internal helper function.
        The output permutations are built up by adding element *e* to the
        current *permutations* at every possible position.
        The key idea is to keep repeated elements (reverse) ordered:
        if e1 == e2 and e1 is before e2 in the iterable, then all permutations
        with e1 before e2 are ignored.

        """ for permutation in permutations : for j in range ( len ( permutation ) ) : yield permutation [ : j ] + [ e ] + permutation [ j : ] if permutation [ j ] == e : break else : yield permutation + [ e ] permutations = [ [ ] ] for e in iterable : permutations = make_new_permutations ( permutations , e ) return ( tuple ( t ) for t in permutations )
python how to generate only half of the permutations
Yield successive distinct permutations of the elements in * iterable * .
def distinct_permutations(iterable):
    """Yield successive distinct permutations of the elements in *iterable*.

        >>> sorted(distinct_permutations([1, 0, 1]))
        [(0, 1, 1), (1, 0, 1), (1, 1, 0)]

    Equivalent to ``set(permutations(iterable))``, except duplicates are not
    generated and thrown away. For larger input sequences this is much more
    efficient.

    Duplicate permutations arise when there are duplicated elements in the
    input iterable. The number of items returned is
    `n! / (x_1! * x_2! * ... * x_n!)`, where `n` is the total number of
    items input, and each `x_i` is the count of a distinct item in the input
    sequence.

    """
    def make_new_permutations(permutations, e):
        """Internal helper function.
        The output permutations are built up by adding element *e* to the
        current *permutations* at every possible position.
        The key idea is to keep repeated elements (reverse) ordered:
        if e1 == e2 and e1 is before e2 in the iterable, then all permutations
        with e1 before e2 are ignored.

        """
        for permutation in permutations:
            for j in range(len(permutation)):
                yield permutation[:j] + [e] + permutation[j:]
                if permutation[j] == e:
                    break
            else:
                yield permutation + [e]

    permutations = [[]]
    for e in iterable:
        permutations = make_new_permutations(permutations, e)

    return (tuple(t) for t in permutations)