permutations with unique values

前端 未结 19 1468
爱一瞬间的悲伤
爱一瞬间的悲伤 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条回答
  •  闹比i
    闹比i (楼主)
    2020-11-22 02:47

    You can make a function that uses collections.Counter to get unique items and their counts from the given sequence, and uses itertools.combinations to pick combinations of indices for each unique item in each recursive call, and map the indices back to a list when all indices are picked:

    from collections import Counter
    from itertools import combinations
    def unique_permutations(seq):
        def index_permutations(counts, index_pool):
            if not counts:
                yield {}
                return
            (item, count), *rest = counts.items()
            rest = dict(rest)
            for indices in combinations(index_pool, count):
                mapping = dict.fromkeys(indices, item)
                for others in index_permutations(rest, index_pool.difference(indices)):
                    yield {**mapping, **others}
        indices = set(range(len(seq)))
        for mapping in index_permutations(Counter(seq), indices):
            yield [mapping[i] for i in indices]
    

    so that [''.join(i) for i in unique_permutations('moon')] returns:

    ['moon', 'mono', 'mnoo', 'omon', 'omno', 'nmoo', 'oomn', 'onmo', 'nomo', 'oonm', 'onom', 'noom']
    

提交回复
热议问题