#python
#python
Вопрос:
Я нахожу исходный код itertools.combinations()
функции на python. Это выглядит так.
def combinations(iterable, r):
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = list(range(r))
print(indices)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i n - r:
break
else:
return
indices[i] = 1
for j in range(i 1, r):
indices[j] = indices[j-1] 1
print(indices)
yield tuple(pool[i] for i in indices)
У меня есть такие кортежи:
pairs = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
Мне нужно сгенерировать четыре пары всех возможных комбинаций, но с условием, что в списке всегда будет только два одинаковых числа. Итак, в этом случае я хочу сгенерировать этот список 3:
((0, 1), (0, 2), (1, 3), (2, 3))
((0, 1), (0, 3), (1, 2), (2, 3))
((0, 2), (0, 3), (1, 2), (1, 3))
Что мне действительно нужно, так это обновить код комбинаций генерации, потому что в моем реальном приложении мне нужно сгенерировать 23-nty из 80 кортежей. Генерация и фильтрация после этого заняли бы много времени, поэтому мне нужно выявить проблему в части генерации.
Комментарии:
1. Пожалуйста, отредактируйте требование «23 из 80» в вашем вопросе. Кроме того, пожалуйста, приведите немного больший пример, чтобы помочь прояснить ситуацию.
2. Вам нужно максимум 2 из любого числа или вам нужно ровно 2? Последнее сложнее, но может быть и быстрее.
3. Под «У меня есть такие кортежи» вы имеете в виду, например
list(it.combinations(range(n), 2))
, для некоторого числаn
? Или кортежи могут быть любыми числами?4. Нет, в списке кортежей всегда есть разные пары чисел.
5. @Prune Да, ровно 2.
Ответ №1:
Вы можете использовать itertools.combinations
, а затем фильтровать результат с помощью collections.Counter
:
from collections import Counter
import itertools as it
pairs = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
result = filter(
lambda x: max(Counter(it.chain(*x)).values()) < 3,
it.combinations(pairs, 4)
)
print(list(result))
Вывод:
[((0, 1), (0, 2), (1, 3), (2, 3)),
((0, 1), (0, 3), (1, 2), (2, 3)),
((0, 2), (0, 3), (1, 2), (1, 3))]
Комментарии:
1. Да, это правда, но мне нужно уловить эту проблему не после генерации всех возможных комбинаций, а по мере генерации комбинаций.
2. @M.Barabas Почему?
it.combinations
это генератор, и на самом деле не имеет значения, где вы выполняете проверку, до или после получения. Вероятно, это не повредит производительности, тем более, что вам не нужно переписывать функцию.3. Потому что этот вопрос был только примером. В моем реальном приложении мне нужно сгенерировать 23-nти из списка, который содержит 80 кортежей. В этом случае потребуется много времени, чтобы сгенерировать все возможные комбинации.