如果python

时间:2018-05-05 15:50:15

标签: python python-3.x

我们说我有一个列表列表,例如:

[[0, 2], [0, 1], [2, 3], [4, 5, 7, 8], [6, 4]]

并且如果列表中的至少一个值与另一个列表中的另一个值相同,我想将列表联合起来,因此在示例中最终结果将是:

[[0, 1, 2, 3], [4, 5, 6, 7, 8]]

我真的不关心列表[0, 1, 2, 3][0, 2, 1, 3]中的值的顺序。

我试过这样做,但它没有用。你有什么想法吗?感谢。

编辑(抱歉没有发布我之前尝试过的代码): 我试图做的是以下几点:

for p in llista:
        for q in p:
            for k in llista:
                if p==k:
                    llista.remove(k)
                else:
                    for h in k:
                        if p!=k:
                            if q==h:
                                k.remove(h)
                                for t in k:
                                    if t not in p:
                                        p.append(t)
    llista_final = [x for x in llista if x != []]

llista 是列表清单。

3 个答案:

答案 0 :(得分:2)

我不得不承认这是一个棘手的问题。我很好奇这个问题代表什么和/或你在哪里找到它......

我最初认为这只是一个图表连接组件问题,但我想从创建图表的显式表示,运行bfs等等中获取快捷方式......

解决方案的想法是这样的:对于每个子列表,检查它是否与任何其他子列表有一些共同的元素,并用它们的联合替换它。

不是非常pythonic,但它是:

def merge(l):
    l = list(map(tuple, l))
    for i, h in enumerate(l):
        sh = set(h)
        for j, k in enumerate(l):
            if i == j: continue
            sk = set(k)
            if sh & sk: # h and k have some element in common
                l[j] = tuple(sh | sk)
    return list(map(list, set(l)))

答案 1 :(得分:1)

这是一个可以完成你想要的功能。我尝试使用自我记录变量名称和注释来帮助您了解此代码的工作原理。据我所知,代码是pythonic。我使用集合来加速并简化一些操作。其缺点是输入列表列表中的项目必须是可清除的,但您的示例使用的整数非常有效。

def cliquesfromlistoflists(inputlistoflists):
    """Given a list of lists, return a new list of lists that unites
    the old lists that have at least one element in common.
    """
    listofdisjointsets = []
    for inputlist in inputlistoflists:
        # Update the list of disjoint sets using the current sublist
        inputset = set(inputlist)
        unionofsetsoverlappinginputset = inputset.copy()
        listofdisjointsetsnotoverlappinginputset = []
        for aset in listofdisjointsets:
            # Unite set if overlaps the new input set, else just store it
            if aset.isdisjoint(inputset):
                listofdisjointsetsnotoverlappinginputset.append(aset)
            else:
                unionofsetsoverlappinginputset.update(aset)
        listofdisjointsets = (listofdisjointsetsnotoverlappinginputset 
                              + [unionofsetsoverlappinginputset])
    # Return the information in a list-of-lists format
    return [list(aset) for aset in listofdisjointsets]

print(cliquesfromlistoflists([[0, 2], [0, 1], [2, 3], [4, 5, 7, 8], [6, 4]]))
# printout is [[0, 1, 2, 3], [4, 5, 6, 7, 8]]

答案 2 :(得分:-1)

此解决方案修改通用广度优先搜索以逐渐减少初始<application>并使用如果找到匹配的组合更新deque列表,或者如果未发现分组则更新列表:

result

输出:

from collections import deque
d = deque([[0,2] , [0,1] , [2,3] , [4,5,7,8] , [6,4]])
result = [d.popleft()]
while d:
  v = d.popleft()
  result = [list(set(i+v)) if any(c in i for c in v) else i for i in result] if any(any(c in i for c in v) for i in result) else result + [v]