使用类似元素

时间:2018-02-03 18:37:27

标签: python-3.x tuples

我必须合并包含至少一个元素的所有元组。

tups=[(1,2),(2,3),(8,9),(4,5),(15,12),(9,6),(7,8),(3,11),(1,15)]

第一元组(1,2)应与(2,3),(3,11),(1,15),(15,12)合并,因为这些元组中的每一个都包含前一元组的类似项。所以最终的输出应该是

lst1 = [1,2,3,11,12,15]
lst2=[6,7,8,9] since (8,9),(9,6) and (7,8) have matching elements

到目前为止我的代码:

finlst=[]
for items in range(len(tups)):
    for resid in range(len(tups)):
        if(tups[items] != tups[resid] ):
            if(tups[items][0]==tups[resid][0] or tups[items][0]==tups[resid][1]):
                finlst.append(list(set(tups[items]+tups[resid])))

2 个答案:

答案 0 :(得分:3)

您可以这样做,使用使用匹配元组扩展的集合:

tups = [(1, 2), (2, 3), (8, 9), (4, 5), (15, 12), (9, 6), (7, 8), (3, 11), (1, 15)]

groups = []
for t in tups:
    for group in groups:
        # find a group that has at least one element in common with the tuple
        if any(x in group for x in t):
            # extend the group with the items from the tuple
            group.update(t)
            # break from the group-loop as we don’t need to search any further
            break
    else:
        # otherwise (if the group-loop ended without being cancelled with `break`)
        # create a new group from the tuple
        groups.append(set(t))


# output
for group in groups:
    print(group)
{1, 2, 3, 11, 15}
{8, 9, 6, 7}
{4, 5}
{12, 15}

由于此解决方案按顺序迭代原始元组列表并按顺序,这对于连接不直接可见的输入不起作用。为此,我们可以使用以下解决方案,使用fixed-point iteration组合这些组,只要它仍然有效:

tups = [(1, 2), (3, 4), (1, 4)]

import itertools

groups = [set(t) for t in tups]
while True:
    for a, b in itertools.combinations(groups, 2):
        # if the groups can be merged
        if len(a & b):
            # construct new groups list
            groups = [g for g in groups if g != a and g != b]
            groups.append(a | b)

            # break the for loop and restart
            break
    else:
        # the for loop ended naturally, so no overlapping groups were found
        break

答案 1 :(得分:0)

我找到了解决方案,更多的是与连接相关的图论问题,Connectivity-Graph Theory

我们可以使用NetworkX,它几乎可以保证是正确的:

def uniqueGroup(groups):
#     grp=[]
#     for group in groups:
#         grp.append(list(group))
#     l=groups

    import networkx 
    from networkx.algorithms.components.connected import connected_components


    def to_graph(groups):
        G = networkx.Graph()
        for part in groups:
            # each sublist is a bunch of nodes
            G.add_nodes_from(part)
            # it also imlies a number of edges:
            G.add_edges_from(to_edges(part))
        return G

    def to_edges(groups):
        """ 
            treat `l` as a Graph and returns it's edges 
            to_edges(['a','b','c','d']) -> [(a,b), (b,c),(c,d)]
        """
        it = iter(groups)
        last = next(it)

        for current in it:
            yield last, current
            last = current    

    G = to_graph(groups)
    return connected_components(G)

输出:

tups = [(1, 2),(3,4),(1,4)]
uniqueGroup(tups)

{1, 2, 3, 4}