如果集合存储在s中,例如:s = [set([1, 2]), set([1, 3]), set([1, 2, 3]), set([2, 4])]
然后可以使用itertools.combinations将它们两个一个地取出来,并计算交集(注意,正如Alex所指出的,combinations只在2.6版之后才可用)。这里有一个列表说明(仅为示例起见):
^{pr2}$
或者,在循环中,这可能是您需要的: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)的列表,而不是{}的列表。在
新格式示例: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]的索引。在