【问题标题】:How do I merge lists with common elements, where these elements themselves are lists/tuples?如何将列表与常见元素合并,这些元素本身就是列表/元组?
【发布时间】:2021-10-29 18:34:01
【问题描述】:

我有这个嵌套列表,我需要以某种方式遍历它以合并具有公共元素的内部列表(其中这些元素本身就是列表)。这是一个具有现有原始数据模式的简化数据:

data = [
        [[0,1],[2,3],[4,5]], 
        [[2,3],[4,5]], 
        [[4,5]], 
        [[6,7],[8,9],[10,11]], 
        [[8,9],[10,11]], 
        [[10,11]], 
        [[12,13],[14,15],[16,17],[18,19],[20,21]], 
        [[14,15],[16,17],[18,19],[20,21]], 
        [[16,17],[18,19],[20,21]],
        [[18,19],[20,21]],
        [[20,21]]
       ]  

我想获得一个合并的嵌套列表,如下所示:

merged = [
      [[0,1],[2,3],[4,5]], 
      [[6,7],[8,9],[10,11]], 
      [[12,13],[14,15],[16,17],[18,19],[20,21]]
     ]

以下是我尝试过的,不幸的是它不会超出第二个内部for loop,而是返回错误AttributeError: 'int' object has no attribute 'values'

tmp = {}
for subl in original:
    subl = list(set(subl))                        # Eliminating duplicates by first converting to a set
    subl = dict(zip(subl, range(len(subl))))      # Create dictionary from list
    sublswitch = {y:x for x,y in subl.items()}    # Swap dictionary key for values and vice versa                
    ii = 0
    for key in sublswitch:            
        tmp.setdefault(key.values(), set()).add(list(key.values())[ii])
        ii += 1                                         

out = []
for k, v in tmp.items():
    out.append([[k, i] for i in v])

【问题讨论】:

    标签: python list dictionary arraylist set


    【解决方案1】:

    更新

    试试这个,

    def sort_list(data):
        data = sorted(data, key=itemgetter(0))
        return_list = []
        for lst in data:
            new_list = sorted(lst, key=itemgetter(0))
            if not return_list:
                return_list.append(new_list)
                continue
            if new_list[0] not in return_list[-1]:
                return_list.append(new_list)
            if new_list[0] in return_list[-1] and len(new_list) > 
                                                    len(return_list[-1]):
                return_list.remove(return_list[-1])
                return_list.append(new_list)
        return return_list
    

    这样您就可以对列表进行排序

    data = [[],
        [[0,1],[2,3]],
        [[0,1],[2,3],[4,5]], 
        [[2,3],[4,5]], 
        [[4,5]], 
        [[6,7],[8,9],[10,11]], 
        [[8,9],[10,11]], 
        [[10,11]], 
        [[12,13],[14,15],[16,17],[18,19],[20,21]], 
        [[14,15],[16,17],[18,19],[20,21]], 
        [[16,17],[18,19],[20,21]],
        [[18,19],[20,21]],
        [[20,21]]
       ] 
    

    [[],
     [[0, 1], [2, 3], [4, 5]],
     [[6, 7], [8, 9], [10, 11]],
     [[12, 13], [14, 15], [16, 17], [18, 19], [20, 21]]]
    

    【讨论】:

    • 感谢您的努力。该解决方案适用于第一个给定组合,但使用此数据组合失败:data = [ [[4,5]], [[2,3],[4,5]], [[0,1],[2,3 ],[4,5]], [[10,11]], [[8,9],[10,11]], [[6,7],[8,9],[10,11]] , [[20,21]], [[18,19],[20,21]], [[16,17],[18,19],[20,21]], [[14,15], [16,17],[18,19],[20,21]], [[12,13],[14,15],[16,17],[18,19],[20,21]] ]。它也因主要数据的某些组合而失败
    • 辛苦了@sarath ravi。更新版本适用于样本数据的所有组合,以及真实数据的一些组合。但是,它在真实数据的某些组合中仍然失败。
    • 能否提供故障数据。只是为了解决问题
    • 以下是使用示例数据的 4 种可能的数据组合。如果它适用于所有 4 个,那么它肯定适用于原始数据。数据 = [ [[0,1]], [[0,1],[2,3]], [[0,1],[2,3],[4,5]], [[6,7 ]], [[6,7],[8,9]], [[6,7],[8,9],[10,11]], [[12,13]], [[12,13 ],[14,15]], [[12,13],[14,15],[16,17]], [[12,13],[14,15],[16,17],[18 ,19]], [[12,13],[14,15],[16,17],[18,19],[20,21]] ]
    • 数据 = [ [[0,1],[2,3],[4,5]], [[2,3],[4,5]], [[4,5 ]], [[6,7],[8,9],[10,11]], [[8,9],[10,11]], [[10,11]], [[12,13 ],[14,15],[16,17],[18,19],[20,21]], [[14,15],[16,17],[18,19],[20,21 ]], [[16,17],[18,19],[20,21]], [[18,19],[20,21]], [[20,21]], ]
    【解决方案2】:

    这是一个使用 O(n) 额外空间的解决方案,它跟踪所有已使用哈希表添加的子列表(因此,所有查找只需 O(1))。

    added = set()
    merged = []
    
    for item in data:
        filtered = list(filter(lambda value: value not in added, map(tuple, item)))
        if filtered:
            added.update(filtered)
            merged.append(list(map(list, filtered)))
    
    print(merged)
    

    输出

    [[[0, 1], [2, 3], [4, 5]], [[6, 7], [8, 9], [10, 11]], [[12, 13], [14, 15], [16, 17], [18, 19], [20, 21]]]
    

    更新

    上述解决方案只能防止重复的列表项在下一个列表中再次出现。在这里,我们不仅要防止它们再次发生,还要将它们合并到现有的上。结果这个算法的时间复杂度有点O(n^2)。

    merged = []
    
    for item in data:
        item_set = set(map(tuple, item))
        for result in merged:
            if result & item_set:
                result.update(item_set)
                break
        else:
            merged.append(item_set)
    
    merged = [sorted(map(list, item)) for item in merged]
    print(merged)
    

    【讨论】:

    • 这很好用@Niel Godfrey Ponciano。即使使用真实数据,它也可以按要求工作。非常感谢。在过去的 4 天里,我一直在与此作斗争。
    • 仍然检查并意识到它失败了,如果数据模式被反转(如果从相反方向观察,原始数据的行为方式)如下:data = [[[0,1] ,[2,3],[4,5]],[[0,1],[2,3]],[[0,1]],[[6,7],[8,9],[ 10,11]],[[6,7],[8,9]],[[6,7]], [[12,13],[14,15],[16,17],[18, 19],[20,21]],[[12,13],[14,15],[16,17],[18,19]],[[12,13],[14,15],[ 16,17]],[[12,13],[14,15]],[[12,13]]]。你能弄清楚问题可能来自哪里吗? @Niel Godfrey Ponciano
    • 我试过你的输入data = [[[0,1],[2,3],[4,5]],[[0,1],[2,3]],[[0,1]], [[6,7],[8,9],[10,11]],[[6,7],[8,9]],[[6,7]], [[12,13],[14,15],[16,17],[18,19],[20,21]],[[12,13],[14,15],[16,17],[18,19]],[[12,13],[14,15],[16,17]],[[12,13],[14,15]],[[12,13]]],结果正确为[[[0, 1], [2, 3], [4, 5]], [[6, 7], [8, 9], [10, 11]], [[12, 13], [14, 15], [16, 17], [18, 19], [20, 21]]]你能检查一下吗? paiza.io/projects/e/k-jm2GcgyJf6IUQikfL8pA?theme=twilight
    • 哦,抱歉,这个可行,但这是反转数据的样子:data = [ [[0,1]], [[0,1],[2,3]], [ [0,1],[2,3],[4,5]], [[6,7]], [[6,7],[8,9]], [[6,7],[8 ,9],[10,11]], [[12,13]], [[12,13],[14,15]], [[12,13],[14,15],[16,17 ]], [[12,13],[14,15],[16,17],[18,19]], [[12,13],[14,15],[16,17],[18 ,19],[20,21]] ]
    • 好的,明白了。您能否针对所有可能的组合重试更新后的解决方案?
    【解决方案3】:

    试试这个循环:

    newdata = []
    for lst in data:
        if newdata:
            x = [i for i in lst if i not in newdata[-1]]
            if x:
                newdata.append(x)
        else:
            newdata.append(lst)
    print(newdata)
    

    输出:

    [[[0, 1], [2, 3], [4, 5]], [[6, 7], [8, 9], [10, 11]], [[12, 13], [14, 15], [16, 17], [18, 19], [20, 21]]]
    

    【讨论】:

    • 非常感谢 @U12-Forward ,但是当我将其适应真实数据时失败了。
    • 适用于样本数据的两种组合,但使用这些组合失败。数据 = [ [[4,5]], [[2,3],[4,5]], [[0,1],[2,3],[4,5]], [[10,11 ]], [[8,9],[10,11]], [[6,7],[8,9],[10,11]], [[20,21]], [[18,19 ],[20,21]], [[16,17],[18,19],[20,21]], [[14,15],[16,17],[18,19],[20 ,21]], [[12,13],[14,15],[16,17],[18,19],[20,21]] ]
    • 还有这个:data = [ [[0,1]], [[0,1],[2,3]], [[0,1],[2,3],[ 4,5]], [[6,7]], [[6,7],[8,9]], [[6,7],[8,9],[10,11]], [[ 12,13]], [[12,13],[14,15]], [[12,13],[14,15],[16,17]], [[12,13],[14, 15],[16,17],[18,19]],[[12,13],[14,15],[16,17],[18,19],[20,21]]]跨度>
    猜你喜欢
    • 2021-06-15
    • 1970-01-01
    • 2016-10-27
    • 2019-05-22
    • 1970-01-01
    • 2016-12-19
    • 2018-04-15
    • 1970-01-01
    相关资源
    最近更新 更多