【问题标题】:Merging sublists that contain common elements [duplicate]合并包含公共元素的子列表[重复]
【发布时间】:2016-11-19 13:59:09
【问题描述】:

我正在尝试编写一个快速函数,该函数将遍历子列表中的元素并在子列表包含元素时合并子列表。例如,列表[[0, 3], [3, 4], [5, 6]] 应该合并到[[0, 3, 4], [5, 6]]. 子列表可以是任意大小,每个子列表可以有不同的大小,因此可以包含许多元素。

到目前为止,我的代码(不起作用)如下所示。出现的错误是:slice indices must be integers or None or have an __index__ method

def join_clusters(clusters):
    for cluster in clusters:
        for j in cluster:
            for k in clusters[cluster:]:
                for h in k:
                    if j == h:
                        cluster.append(k)
                        clusters.pop(k)
                        return clusters

【问题讨论】:

  • 您只想合并相邻的子列表吗? [[1,2,3], [3,4,5], [5,6,7]] 会合并到 [[1,2,3,4,5,6,7]] 吗?
  • @PM2Ring 我想是的,我就是这样做的
  • 我认为您正在尝试解决集合合并/连接组件/联合查找问题-在这种情况下,它与许多以前的问题重复-但您的示例有点令人困惑,因为它可以解释为连接相邻链。 [[1,2],[3,1],[1,3]] 应该变成 [[1,2,3]] 吗?
  • 是的,这就是我所需要的。 [[1,2],[3,1],[1,3]] 将变为 [[1,2,3]]

标签: python


【解决方案1】:

如果子集是排序的,我会尝试对集合做一些事情。

from itertools import islice

def merge(T):
  idx = 0
  result = [set(T[0])]
  for sublst in islice(T, 1, len(T)):
    subset = set(sublst)
    if result[idx] & subset:
      result[idx].update(subset)
    else:
      result.append(set(sublst))
      idx += 1
  return [sorted(sub) for sub in result]

【讨论】:

    【解决方案2】:

    这是一个适用于任何类型的子列表的解决方案,无论它是否已排序:

    def join_clusters(clusters):
        result = clusters[:1]                          #1
        for cluster in clusters[1:]:
            if cluster[0] == result[-1][-1]:
                result[-1] = result[-1] + cluster[1:]  #2
            else:
                result.append(cluster)                 #3
        return result
    

    例子:

    >>> c1 = [[0, 3], [3, 4], [5, 6]]
    >>> join_clusters(c1)
    [[0, 3, 4], [5, 6]]
    

    >>> c2 = [[3, 1], [1, 2], [1, 3], [2, 1], [1, 3], [3, 1], [1, 2]]
    >>> join_clusters(c2)
    [[3, 1, 2], [1, 3], [2, 1, 3, 1, 2]]
    

    >>> les_mis = "At the end of the day you're another day older".split()
    >>> join_clusters(les_mis)
    ['Athend', 'of', 'the', "dayou're", 'another', 'day', 'older']
    

    注意事项:

    #1:如果您希望输出仅包含输入的副本,而不是实际的原始子列表,请使用 result = clusters[:1][:]

    #2result[-1] += cluster[1:] 没有被使用,因为它会改变原始列表的元素,这可能是不可取的。

    #3:如果您希望输出仅包含输入的副本,而不是实际的原始子列表,请使用 result.append(cluster[:])

    【讨论】:

    • 有什么办法可以删除重复的,让[2, 1, 3, 1, 2]变成[1,2,3](顺序不重要)
    • 另外,有什么方法可以改变列表集群,而不是创建一个副本?
    • 1.并非没有从头开始——看起来我以为你问的问题不是你想要答案的问题。 2. 嗯,是的,但是考虑到 #1 似乎没什么意义 ;-)
    • 感谢您的帮助。
    【解决方案3】:

    我使用了一个 while 循环,以便更轻松地引用列表中的下一个集群

    def join_clusters(clusters):
        idx = 0
        while idx < len(clusters) - 1:
            for element in clusters[idx]:
                if element in clusters[idx + 1]:
                    clusters[idx].remove(element)
                    clusters[idx] = clusters[idx] + clusters[idx + 1]                
                    del(clusters[idx + 1])
                    break
            idx = idx + 1
        return clusters
    

    希望这对你有帮助:)

    【讨论】:

    • 我的错误,谢谢指出
    • 非常感谢
    • 非常感谢,这正是我需要的!
    • @你好没问题:)
    猜你喜欢
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    相关资源
    最近更新 更多