Наивный подход может заключаться в том, чтобы взять набор перестановок:
list(set(it.permutations([1, 1, 1])))
# [(1, 1, 1)]
Однако этот метод расточительно вычисляет репликативные перестановки и отбрасывает их. Более эффективным подходом будет more_itertools.distinct_permutations
, сторонний инструмент .
Код
import itertools as it
import more_itertools as mit
list(mit.distinct_permutations([1, 1, 1]))
# [(1, 1, 1)]
Производительность
Используя большую итерацию, мы сравним характеристики между наивными и сторонними методами.
iterable = [1, 1, 1, 1, 1, 1]
len(list(it.permutations(iterable)))
# 720
%timeit -n 10000 list(set(it.permutations(iterable)))
# 10000 loops, best of 3: 111 µs per loop
%timeit -n 10000 list(mit.distinct_permutations(iterable))
# 10000 loops, best of 3: 16.7 µs per loop
Мы видим, что more_itertools.distinct_permutations
на порядок быстрее.
Подробности
Из исходного кода алгоритм рекурсии (как показано в принятом ответе) используется для вычисления различных перестановок, тем самым устраняя расточительные вычисления. Подробнее см. Исходный код .