permutations with unique values

前端 未结 19 1434
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-22 01:53

itertools.permutations generates where its elements are treated as unique based on their position, not on their value. So basically I want to avoid duplicates like this:

19条回答
  •  醉话见心
    2020-11-22 02:23

    Came across this the other day while working on a problem of my own. I like Luka Rahne's approach, but I thought that using the Counter class in the collections library seemed like a modest improvement. Here's my code:

    def unique_permutations(elements):
        "Returns a list of lists; each sublist is a unique permutations of elements."
        ctr = collections.Counter(elements)
    
        # Base case with one element: just return the element
        if len(ctr.keys())==1 and ctr[ctr.keys()[0]] == 1:
            return [[ctr.keys()[0]]]
    
        perms = []
    
        # For each counter key, find the unique permutations of the set with
        # one member of that key removed, and append the key to the front of
        # each of those permutations.
        for k in ctr.keys():
            ctr_k = ctr.copy()
            ctr_k[k] -= 1
            if ctr_k[k]==0: 
                ctr_k.pop(k)
            perms_k = [[k] + p for p in unique_permutations(ctr_k)]
            perms.extend(perms_k)
    
        return perms
    

    This code returns each permutation as a list. If you feed it a string, it'll give you a list of permutations where each one is a list of characters. If you want the output as a list of strings instead (for example, if you're a terrible person and you want to abuse my code to help you cheat in Scrabble), just do the following:

    [''.join(perm) for perm in unique_permutations('abunchofletters')]
    

提交回复
热议问题