Кажется, что, несмотря на то, что в сети имеется множество алгоритмов и функций для создания уникальных комбинаций любого размера из списка уникальных элементов, в случае списка уникальных элементов нет доступных (т.е. список, содержащий повторения одного значения.)
Вопрос заключается в том, как генерировать ON-THE-FLY в функции генератора все уникальные комбинации из уникального списка безвычислительная дорогостоящая потребность в фильтрации дубликатов?
Теперь, когда есть мотивированный ответ на вопрос, легче дать более ясную информацию о том, чего я ожидаю достичь:
Сначала дайте код, иллюстрирующий, как проверить, является ли комбинация comboB
дубликат другого (comboA
):
comboA = [1,2,2]
comboB = [2,1,2]
print("B is a duplicate of A:", comboA.sort()==comboB.sort())
В данном примере B - это дубликат A, а print() печатает True.
Проблема получения функции генератора, способной обеспечить уникальные комбинации "на лету" в случае неуникального списка, решается здесь: Получение уникальных комбинаций из уникального списка элементов, FASTER?, но предоставленная функция генератора нуждается в поиске и требует памяти, что вызывает проблемы в случае огромного количества комбинаций.
В текущей версии предоставленной функции ответа функция выполняет работу без каких-либо поисков и представляется правильным ответом здесь, НО...
Целью избавления от поиска является ускорение генерации уникальных комбинаций в случае списка с дубликатами.
Я изначально (написав первую версию этого вопроса) ошибочно предположил, что код, который не требует создания набора, используемого для поиска, необходимого для обеспечения уникальности, как ожидается, даст преимущество над кодами, нуждающимися в поиске. Это не тот случай. По крайней мере, не всегда. Код, который до сих пор предоставлял ответ, не использует поисковые запросы, но занимает гораздо больше времени для создания всех комбинаций в случае отсутствия избыточного списка или если в списке имеется только несколько избыточных элементов.
Здесь приведены некоторые тайминги для иллюстрации текущей ситуации:
-----------------
k: 6 len(ls): 48
Combos Used Code Time
---------------------------------------------------------
12271512 len(list(combinations(ls,k))) : 2.036 seconds
12271512 len(list(subbags(ls,k))) : 50.540 seconds
12271512 len(list(uniqueCombinations(ls,k))) : 8.174 seconds
12271512 len(set(combinations(sorted(ls),k))): 7.233 seconds
---------------------------------------------------------
12271512 len(list(combinations(ls,k))) : 2.030 seconds
1 len(list(subbags(ls,k))) : 0.001 seconds
1 len(list(uniqueCombinations(ls,k))) : 3.619 seconds
1 len(set(combinations(sorted(ls),k))): 2.592 seconds
Над таймингами показаны две крайности: нет дубликатов и только дубликатов. Все остальные тайминги находятся между этими двумя.
Моя интерпретация приведенных выше результатов заключается в том, что чистая функция Python (без itertools или других C-скомпилированных модулей) может быть чрезвычайно быстрой, но она может быть намного медленнее в зависимости от того, сколько дубликатов в списке. Таким образом, возможно, нет возможности писать код на С++ для модуля расширения Python.so, обеспечивающего требуемую функциональность.