我想将集合与常用元素合并。例如
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])])
实现这一目标的有效方法是什么?
答案 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))