permutations with unique values

前端 未结 19 1684
爱一瞬间的悲伤
爱一瞬间的悲伤 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
    2020-11-22 02:28

    Roughly as fast as Luka Rahne's answer, but shorter & simpler, IMHO.

    def unique_permutations(elements):
        if len(elements) == 1:
            yield (elements[0],)
        else:
            unique_elements = set(elements)
            for first_element in unique_elements:
                remaining_elements = list(elements)
                remaining_elements.remove(first_element)
                for sub_permutation in unique_permutations(remaining_elements):
                    yield (first_element,) + sub_permutation
    
    >>> list(unique_permutations((1,2,3,1)))
    [(1, 1, 2, 3), (1, 1, 3, 2), (1, 2, 1, 3), ... , (3, 1, 2, 1), (3, 2, 1, 1)]
    

    It works recursively by setting the first element (iterating through all unique elements), and iterating through the permutations for all remaining elements.

    Let's go through the unique_permutations of (1,2,3,1) to see how it works:

    • unique_elements are 1,2,3
    • Let's iterate through them: first_element starts with 1.
      • remaining_elements are [2,3,1] (ie. 1,2,3,1 minus the first 1)
      • We iterate (recursively) through the permutations of the remaining elements: (1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)
      • For each sub_permutation, we insert the first_element: (1,1,2,3), (1,1,3,2), ... and yield the result.
    • Now we iterate to first_element = 2, and do the same as above.
      • remaining_elements are [1,3,1] (ie. 1,2,3,1 minus the first 2)
      • We iterate through the permutations of the remaining elements: (1, 1, 3), (1, 3, 1), (3, 1, 1)
      • For each sub_permutation, we insert the first_element: (2, 1, 1, 3), (2, 1, 3, 1), (2, 3, 1, 1)... and yield the result.
    • Finally, we do the same with first_element = 3.

提交回复
热议问题