【问题标题】:Merging sets with common elements? [duplicate]合并具有共同元素的集合? [复制]
【发布时间】:2017-02-13 19:24:59
【问题描述】:

我想将集合与公共元素合并。例如

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])])

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

【问题讨论】:

  • @AustinHastings 使用集合,此操作更快、更容易。我已经发布了一个合适的策略。
  • @TemporalWolf 解决方案涉及集合,对于列表、元组等也是如此。您想将一堆集合合并在一起吗?构建集。
  • 连接组件方法比蛮力的全对set.union/set.intersection 算法效率更高。

标签: python set


【解决方案1】:

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


这个答案从高层次上解释了如何实现你想要的。如果你想要一个具体的解决方案,你必须首先展示你为解决问题所做的努力。

【讨论】:

  • 我没有投票给你。
  • @nos 这并没有改变我只提供同等努力的政策 -> 我不介意帮助你弄清楚如何去做,但你必须努力解决它.
【解决方案2】:

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

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。它首先构建一个新图的邻接表,每个节点对应input 的一个frozenset 元素。如果两个节点 (frozensets) 共享公共元素,则它们之间存在一条边。然后使用深度优先图遍历来找到这个新图的连通分量。

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))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多