【问题标题】:How to merge list of dictionaries in python in shortest and fastest way possible?如何以最短和最快的方式合并python中的字典列表?
【发布时间】:2022-01-19 04:26:27
【问题描述】:

我想在 python 中合并字典列表。列表中包含的字典数量不是固定的,嵌套字典正在合并到相同和不同的键上。列表中的字典不包含嵌套字典。来自相同键的值可以存储在列表中。

我的代码是:

list_of_dict = [{'a': 1, 'b': 2, 'c': 3}, {'a': 3, 'b': 5}, {'k': 5, 'j': 5}, {'a': 3, 'k': 5, 'd': 4}, {'a': 3} ...... ]
output = {}

for i in list_of_dict:
    for k,v in i.items():
        if k in output:
            output[k].append(v)
        else:
            output[k] = [v]

有没有更短、更快的实现方式?

我实际上正在尝试实现最快的方法,因为字典列表非常大,然后有很多行包含此类数据。

【问题讨论】:

  • 什么是list_of_dict.items()list 没有 items() 方法。
  • 这个问题正在meta讨论。

标签: python list dictionary merge


【解决方案1】:

一种使用collections.defaultdict的方式:

from collections import defaultdict

res = defaultdict(list)

for d in list_of_dict:
    for k, v in d.items():
        res[k].append(v)

输出:

defaultdict(list,
            {'a': [1, 3, 3, 3],
             'b': [2, 5],
             'c': [3],
             'k': [5, 5],
             'j': [5],
             'd': [4]})

【讨论】:

  • 从我的测试来看,这似乎是最快的。
  • @justhalf 和最易读的,IMO
  • 是的,我想知道为什么 OP 没有 cmets 并突然接受了没有 cmets 的最新答案。
【解决方案2】:

items() 是一个字典方法,但list_of_dict 是一个列表。您需要一个嵌套循环,这样您就可以遍历字典,然后遍历每个字典的项目。

ou = {}
for d in list_of_dict:
    for key, value in d.items():
        output.setdefault(key, []).append(value)

【讨论】:

    【解决方案3】:

    另一个缩短版本可以,

    list_of_dict = [{'a': 1, 'b': 2, 'c': 3}, {'a': 3, 'b': 5}, {'k': 5, 'j': 5}, {'a': 3, 'k': 5, 'd': 4}, {'a': 3}]
    
    output = {
        k: [d[k] for d in list_of_dict if k in d]
        for k in set().union(*list_of_dict)
    }
    print(output)
    {'d': [4], 'k': [5, 5], 'a': [1, 3, 3, 3], 'j': [5], 'c': [3], 'b': [2, 5]}
    

    【讨论】:

    • 我也是这么想的,但是你认为这会比嵌套循环的直接解决方案更快吗? (也可以将d.get(k)替换为k in d
    • 我刚刚在 1000 行每行 100 个条目上进行了测试(平均超过 100 次试验),如果使用 d.get(k),嵌套循环版本似乎快了大约 10%,但使用 k in d 这个方法快 45%。
    【解决方案4】:

    一种最短的方法是

    • 准备所有字典中所有键的列表/集合
    • 并在列表中的所有字典上调用该键。

    list_of_dict = [{'a': 1, 'b': 2, 'c': 3}, {'a': 3, 'b': 5}, {'k': 5, 'j': 5}, {'a': 3, 'k': 5, 'd': 4}, {'a': 3}]
    
    # prepare a list/set of all the keys from all the dictionaries
    
    # method 1: use sum 
    all_keys = sum([[a for a in x.keys()] for x in list_of_dict], [])
    
    # method 2: use itertools 
    import itertools
    all_keys = list(itertools.chain.from_iterable(list_of_dict))
    
    # method 3: use union of the set
    all_keys = set().union(*list_of_dict)
    
    print(all_keys)
    # ['a', 'b', 'c', 'a', 'b', 'k', 'j', 'a', 'k', 'd', 'a']
    
    # convert the list to set to remove duplicates 
    all_keys = set(all_keys)
    print(all_keys)
    # {'a', 'k', 'c', 'd', 'b', 'j'}
    
    # now merge the dictionary
    merged = {k: [d.get(k) for d in list_of_dict if k in d] for k in all_keys}
    print(merged)
    # {'a': [1, 3, 3, 3], 'k': [5, 5], 'c': [3], 'd': [4], 'b': [2, 5], 'j': [5]}
    

    简而言之:

    all_keys = set().union(*list_of_dict)
    merged = {k: [d.get(k) for d in list_of_dict if k in d] for k in all_keys}
    
    print(merged)
    # {'a': [1, 3, 3, 3], 'k': [5, 5], 'c': [3], 'd': [4], 'b': [2, 5], 'j': [5]}
    

    【讨论】:

    • 获取密钥,set().union(*list_of_dicts))会更好吗?
    • 对于未来的读者,这个答案有一个已删除的评论,讨论过on this meta post
    猜你喜欢
    • 2019-03-13
    • 2011-11-11
    • 2012-03-09
    • 2022-07-21
    • 2010-11-21
    • 2020-12-25
    • 1970-01-01
    • 2019-03-07
    • 2021-09-07
    相关资源
    最近更新 更多