【问题标题】:Merge tuples with the same key合并具有相同键的元组
【发布时间】:2018-09-22 07:42:54
【问题描述】:

如何合并具有相同键的元组

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

把它们变成

list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]

【问题讨论】:

标签: python tuples


【解决方案1】:

最高效的方法是使用collections.defaultdict 字典将数据存储为扩展列表,然后在需要时转换回元组/列表:

import collections

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

c = collections.defaultdict(list)
for a,b in list_1:
    c[a].extend(b)  # add to existing list or create a new one

list_2 = list(c.items())

结果:

[('AAW', [147, 124]), ('AAA', [123, 456])]

请注意,转换后的数据最好保留为字典。再次转换为列表会失去字典的“关键”功能。

另一方面,如果您想保留原始元组列表的“键”的顺序,除非您使用的是 python 3.6/3.7,否则您必须使用原始“键”创建一个列表"(有序,唯一),然后从字典中重建列表。或者使用OrderedDict,但是你不能使用defaultdict(或者使用recipe

【讨论】:

  • 请注意,如果需要考虑,此答案不一定会保留原始列表的顺序。
  • true,除非您使用的是 python 3.7。要保留原始顺序,您必须使用原始“键”(有序、唯一)创建一个列表,然后从字典中重建该列表。
【解决方案2】:

您可以使用 dict 来跟踪每个键的索引以保持时间复杂度 O(n):

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
list_2 = []
i = {}
for k, s in list_1:
    if k not in i:
        list_2.append((k, s))
        i[k] = len(i)
    else:
        list_2[i[k]][1].extend(s)

list_2 会变成:

[('AAA', [123, 456]), ('AAW', [147, 124])]

【讨论】:

    【解决方案3】:

    您可以创建字典并在列表中循环。如果字典中存在的项目将该值附加到已经存在的列表中,则将该值分配给键。

    dict_1 = {}
    for item in list_1:
        if item[0] in dict_1:
            dict_1[item[0]].append(item[1][0])
        else:
            dict_1[item[0]] = item[1]
    list_2 = list(dict_1.items())
    

    【讨论】:

    • 它进行合并但不保留列表中的原始顺序。我得到的结果是:[('AAW', [147, 124]), ('AAA', [123, 456])] - AAA 应该是原始列表中的第一个元素。
    • 如果顺序很重要,那么我们可以使用集合中的 OrderedDict from collections import OrderedDict dict_1 = OrderedDict()
    【解决方案4】:

    与其他答案类似,您可以使用字典将每个键与值列表相关联。这是在下面代码sn-p中的函数merge_by_keys中实现的。

    import pprint
    
    list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
    
    def merge_by_key(ts):
    
        d = {}
        for t in ts:
            key = t[0]
            values = t[1]
            if key not in d:
                d[key] = values[:]
            else:
                d[key].extend(values)
    
        return d.items()
    
    
    
    result = merge_by_key(list_1)
    
    pprint.pprint(result)
    

    【讨论】:

    • @codeforester 只是一个失误。我的代码中有 list_2 以便在计算结果后打印它,以检查我的解决方案是否正确。实际上现在就删除了。
    猜你喜欢
    • 2015-01-21
    • 2021-12-09
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    相关资源
    最近更新 更多