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 yielding from ``set(permutations(iterable))``, except duplicates are not generated and thrown away. For larger
(iterable, r=None)
| 743 | |
| 744 | |
| 745 | def distinct_permutations(iterable, r=None): |
| 746 | """Yield successive distinct permutations of the elements in *iterable*. |
| 747 | |
| 748 | >>> sorted(distinct_permutations([1, 0, 1])) |
| 749 | [(0, 1, 1), (1, 0, 1), (1, 1, 0)] |
| 750 | |
| 751 | Equivalent to yielding from ``set(permutations(iterable))``, except |
| 752 | duplicates are not generated and thrown away. For larger input sequences |
| 753 | this is much more efficient. |
| 754 | |
| 755 | Duplicate permutations arise when there are duplicated elements in the |
| 756 | input iterable. The number of items returned is |
| 757 | `n! / (x_1! * x_2! * ... * x_n!)`, where `n` is the total number of |
| 758 | items input, and each `x_i` is the count of a distinct item in the input |
| 759 | sequence. The function :func:`multinomial` computes this directly. |
| 760 | |
| 761 | If *r* is given, only the *r*-length permutations are yielded. |
| 762 | |
| 763 | >>> sorted(distinct_permutations([1, 0, 1], r=2)) |
| 764 | [(0, 1), (1, 0), (1, 1)] |
| 765 | >>> sorted(distinct_permutations(range(3), r=2)) |
| 766 | [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)] |
| 767 | |
| 768 | *iterable* need not be sortable, but note that using equal (``x == y``) |
| 769 | but non-identical (``id(x) != id(y)``) elements may produce surprising |
| 770 | behavior. For example, ``1`` and ``True`` are equal but non-identical: |
| 771 | |
| 772 | >>> list(distinct_permutations([1, True, '3'])) # doctest: +SKIP |
| 773 | [ |
| 774 | (1, True, '3'), |
| 775 | (1, '3', True), |
| 776 | ('3', 1, True) |
| 777 | ] |
| 778 | >>> list(distinct_permutations([1, 2, '3'])) # doctest: +SKIP |
| 779 | [ |
| 780 | (1, 2, '3'), |
| 781 | (1, '3', 2), |
| 782 | (2, 1, '3'), |
| 783 | (2, '3', 1), |
| 784 | ('3', 1, 2), |
| 785 | ('3', 2, 1) |
| 786 | ] |
| 787 | """ |
| 788 | |
| 789 | # Algorithm: https://w.wiki/Qai |
| 790 | def _full(A): |
| 791 | while True: |
| 792 | # Yield the permutation we have |
| 793 | yield tuple(A) |
| 794 | |
| 795 | # Find the largest index i such that A[i] < A[i + 1] |
| 796 | for i in range(size - 2, -1, -1): |
| 797 | if A[i] < A[i + 1]: |
| 798 | break |
| 799 | # If no such index exists, this permutation is the last one |
| 800 | else: |
| 801 | return |
| 802 |
nothing calls this directly
no test coverage detected
searching dependent graphs…