合并集合与共同元素?

时间:2017-02-13 19:24:59

标签: python set

我想将集合与常用元素合并。例如

input = set([frozenset([1,2,3,4]), frozenset([3,4,5,6,7,8]),  frozenset([1,1000]),
             frozenset([100, 200]), frozenset([100, 300, 400])])

结果:

set([frozenset([1,2,3,4,5,6,7,8, 1000]), frozenset([100,200,300,400])])

实现这一目标的有效方法是什么?

2 个答案:

答案 0 :(得分:1)

使用内置set.union() - >仅包括set.intersection()的长度大于0的结果。

这个答案从高层次解释了如何实现你想要的东西。如果您需要特定的解决方案,则必须首先展示您为解决问题所做的努力。

答案 1 :(得分:1)

这是我尝试过的。首先,我做了一些简单但错误的事情

result = set()
while input:                                                                   
    r = set(input.pop())
    for rr in input.copy():
        if rr & r:                                                  
            input.remove(rr)
            r.update(rr)  
    result.add(frozenset(r))   

此代码的问题在于合并可能不完整,具体取决于input.pop()的顺序。假设input={frozenset([0, 1]), frozenset([2,3]), frozenset([1,2])}和三个元素在此分配顺序中弹出并循环,然后results={frozenset([0,1,2]), frozenset([2,3])}

然后我实施了答案in this post。它首先构建新图的邻接列表,每个节点对应frozenset的一个input元素。如果两个节点(frozenset s)共享公共元素,则存在边缘。然后使用深度优先图遍历来查找这个新图的连通分量。

result, visited = set(), set()
components = collections.defaultdict(list)
adj_list = collections.defaultdict(list)

def dft(node, key):
    visited.add(node)
    components[key].append(node)
    for neighbor in adj_list[node]:
        if neighbor not in visited:
            dft(neighbor, key)

for r1, r2 in itertools.combinations_with_replacement(input, 2):
    if r1 & r2:
        adj_list[r1].append(r2)
        adj_list[r2].append(r1)
for node in adj_list:
    if node not in visited:
        dft(node, node)

for node, neighbors in components.iteritems():
    result.add(node.union(*neighbors))