Если ваши наборы хранятся в s, например:
s = [set([1, 2]), set([1, 3]), set([1, 2, 3]), set([2, 4])]
Затем вы можете использовать itertools.combinations, чтобы взять их два на два и вычислить пересечение (обратите внимание, что, как указал Алекс, combinations
доступно только с версии 2.6). Здесь со списком (просто для примера):
from itertools import combinations
[ i[0] & i[1] for i in combinations(s,2) ]
Или в цикле, что, вероятно, вам нужно:
for i in combinations(s, 2):
inter = i[0] & i[1]
# processes the intersection set result "inter"
Итак, чтобы иметь длину каждого из них, эта «обработка» будет:
l = len(inter)
Это было бы весьма эффективно, так как он использует итераторы для вычисления всех комбинаций и не подготавливает их все заранее.
Изменить. Обратите внимание, что при использовании этого метода каждый набор в списке "s" может фактически быть чем-то другим, что возвращает набор, например генератором. Сам список может быть просто генератором, если у вас мало памяти. Это может быть намного медленнее, в зависимости от того, как вы генерируете эти элементы, но вам не нужно будет одновременно иметь весь список наборов в памяти (не то чтобы это должно быть проблемой в вашем случае).
Например, если каждый набор сделан из функции gen
:
def gen(parameter):
while more_sets():
# ... some code to generate the next set 'x'
yield x
with open("results", "wt") as f_results:
for i in combinations(gen("data"), 2):
inter = i[0] & i[1]
f_results.write("%d\n" % len(inter))
Редактировать 2: Как собирать индексы (после комментария Redrat).
Помимо быстрого решения, на которое я ответил в комментарии, более эффективным способом сбора установленных индексов было бы иметь список (index, set)
вместо списка set
.
Пример с новым форматом:
s = [(0, set([1, 2])), (1, set([1, 3])), (2, set([1, 2, 3]))]
Если вы в любом случае создаете этот список для расчета комбинаций, его должно быть просто адаптировать к вашим новым требованиям. Основной цикл становится:
with open("results", "wt") as f_results:
for i in combinations(s, 2):
inter = i[0][1] & i[1][1]
f_results.write("length of %d & %d: %d\n" % (i[0][0],i[1][0],len(inter))
В цикле i[0]
и i[1]
будут кортежем (index, set)
, поэтому i[0][1]
— это первый набор, i[0][0]
его индекс.
person
RedGlyph
schedule
18.11.2009