将集合与非空交集合并的最简单方法

时间:2014-06-15 08:13:46

标签: python set

我有这个集合列表mergeList,我使用下面的代码合并mergeList中具有非空交集的那些集合。但它并没有将所有集合与交集合并,即在while循环之后,列表中仍有一些集合与交集。

mergeList = [set([0.5]), set([1.5]), set([2.5]), set([3.5]), set([4.5]), set([5.5]), set([2.5, 6.5]), set([6.5]), set([1.5, 7.5]), set([7.5]), set([8.5]), set([0.5, 9.5]), set([9.5]), set([10.5]), set([11.5]), set([12.5]), set([13.5]), set([2.5, 14.5]), set([14.5]), set([8.5, 15.5]), set([15.5]), set([16.5]), set([15.5, 17.5]), set([13.5, 17.5]), set([17.5]), set([8.5, 18.5]), set([18.5]), set([11.5, 19.5]), set([19.5]), set([4.5, 20.5]), set([10.5, 20.5]), set([20.5]), set([8.5, 21.5]), set([21.5]), set([3.5, 22.5]), set([8.5, 22.5]), set([22.5]), set([11.5, 23.5]), set([23.5]), set([12.5, 24.5]), set([24.5]), set([19.5, 25.5]), set([25.5]), set([12.5, 26.5]), set([26.5]), set([27.5]), set([0.5, 28.5]), set([9.5, 28.5]), set([28.5]), set([11.5, 29.5]), set([23.5, 29.5]), set([29.5]), set([5.5, 30.5]), set([30.5]), set([5.5, 31.5]), set([31.5]), set([2.5, 32.5]), set([32.5]), set([16.5, 33.5]), set([33.5]), set([2.5, 34.5]), set([34.5]), set([2.5, 35.5]), set([16.5, 35.5]), set([35.5]), set([12.5, 36.5]), set([9.5, 36.5]), set([36.5]), set([11.5, 37.5]), set([19.5, 37.5]), set([27.5, 37.5]), set([37.5]), set([38.5]), set([39.5]), set([34.5, 40.5]), set([2.5, 40.5]), set([40.5]), set([29.5, 41.5]), set([41.5]), set([13.5, 42.5]), set([17.5, 42.5]), set([42.5]), set([4.5, 43.5]), set([43.5]), set([5.5, 44.5]), set([44.5]), set([43.5, 45.5]), set([45.5]), set([36.5, 46.5]), set([46.5]), set([19.5, 47.5]), set([47.5]), set([13.5, 48.5]), set([48.5]), set([11.5, 49.5]), set([29.5, 49.5]), set([49.5]), set([9.5, 50.5]), set([50.5]), set([30.5, 51.5]), set([1.5, 51.5]), set([51.5]), set([35.5, 52.5]), set([2.5, 52.5]), set([6.5, 52.5]), set([16.5, 52.5]), set([52.5]), set([53.5]), set([43.5, 54.5]), set([4.5, 54.5]), set([54.5]), set([2.5, 55.5]), set([55.5]), set([1.5, 56.5]), set([56.5]), set([8.5, 57.5]), set([57.5]), set([38.5, 58.5]), set([58.5]), set([13.5, 59.5]), set([48.5, 59.5]), set([59.5]), set([10.5, 60.5]), set([20.5, 60.5]), set([60.5]), set([61.5]), set([9.5, 62.5]), set([62.5]), set([47.5, 63.5]), set([25.5, 63.5]), set([63.5]), set([0.5, 64.5]), set([64.5]), set([46.5, 65.5]), set([65.5]), set([16.5, 66.5]), set([35.5, 66.5]), set([66.5]), set([15.5, 67.5]), set([17.5, 67.5]), set([67.5]), set([16.5, 68.5]), set([68.5]), set([53.5, 69.5]), set([69.5]), set([0.5, 70.5]), set([70.5]), set([51.5, 71.5]), set([1.5, 71.5]), set([71.5]), set([70.5, 72.5]), set([0.5, 72.5]), set([72.5]), set([69.5, 73.5]), set([73.5]), set([1.5, 74.5]), set([56.5, 74.5]), set([74.5]), set([10.5, 75.5]), set([75.5]), set([14.5, 76.5]), set([2.5, 76.5]), set([76.5]), set([19.5, 77.5]), set([77.5]), set([2.5, 78.5]), set([58.5, 78.5]), set([40.5, 78.5]), set([78.5]), set([0.5, 79.5]), set([72.5, 79.5]), set([79.5]), set([39.5, 80.5]), set([80.5]), set([29.5, 81.5]), set([41.5, 81.5]), set([81.5]), set([19.5, 82.5]), set([82.5]), set([37.5, 83.5]), set([11.5, 83.5]), set([19.5, 83.5]), set([83.5]), set([11.5, 84.5]), set([84.5]), set([27.5, 85.5]), set([45.5, 85.5]), set([85.5]), set([64.5, 86.5]), set([0.5, 86.5]), set([86.5]), set([65.5, 87.5]), set([9.5, 87.5]), set([46.5, 87.5]), set([36.5, 87.5]), set([87.5]), set([38.5, 88.5]), set([88.5]), set([34.5, 89.5]), set([58.5, 89.5]), set([89.5]), set([4.5, 90.5]), set([90.5]), set([12.5, 91.5]), set([26.5, 91.5]), set([91.5]), set([64.5, 92.5]), set([92.5]), set([3.5, 93.5]), set([22.5, 93.5]), set([8.5, 93.5]), set([93.5]), set([0.5, 94.5]), set([94.5]), set([48.5, 95.5]), set([42.5, 95.5]), set([13.5, 95.5]), set([95.5]), set([19.5, 96.5]), set([96.5]), set([12.5, 97.5]), set([91.5, 97.5]), set([97.5]), set([20.5, 98.5]), set([4.5, 98.5]), set([98.5]), set([8.5, 99.5]), set([99.5]), set([16.5, 100.5]), set([66.5, 100.5]), set([100.5])]

while i < len(mergeList):
    for j in range(len(mergeList) - 1, i, -1):
        if not mergeList[i].isdisjoint(mergeList[j]):
            mergeList[i] = mergeList[i].union(mergeList[j])
            del mergeList[j]

知道这里有什么问题吗?

更新:我添加了一些样本数据,我希望它不会让问题变得复杂。

3 个答案:

答案 0 :(得分:3)

出现问题是因为在检查交叉点之前,两个集合可能不会开始交叉。

假设您有ABC,其中CAB相交。您执行以下操作。

  1. 检查AB是否有交集。没有交集。
  2. 检查AC是否有交集。它们相交,因此您将A替换为A.union(C)并删除C。现在AB相交,而C已消失。
  3. 您已完成A。你继续B,但没有什么可以比较它。你停下来。
  4. 简单,快速的解决方法是继续检查与其他集合交叉的集合,直到您通过所有其他集合而不找到任何集合。

答案 1 :(得分:0)

如果我过度简化问题,请告诉我,但你不能这样做吗?

reduce(lambda a,b: a|b, mergeList)

这里我们定义一个lambda函数来合并集合(它删除了交集中的重复条目)。将其放在reduce函数中会将其应用于累积集a以及列表b中的每个附加集。

答案 2 :(得分:0)

现在我明白了这个问题。问题是可能存在需要合并到第i个条目中的其他后续值。因此,您必须重复,直到不做任何更改。

示例:

{1} {2} {2 3}

OP的算法将{1}合并到{2} - &gt; {1,2} {2,3}。

在此步骤之后,它将设置i = 1,并且不再查看{1,2}集。

i = 0
while i < len(mergeList):
    changes = True
    while changes:
        changes = False
        for j in range(len(mergeList) - 1, i, -1):
            if not mergeList[i].isdisjoint(mergeList[j]):
                changes = True
                mergeList[i] |= mergeList[j]
                del mergeList[j]
    i += 1