如何将字典列表合并到单个字典中?

Posted

技术标签:

【中文标题】如何将字典列表合并到单个字典中?【英文标题】:How do I merge a list of dicts into a single dict? 【发布时间】:2011-03-30 12:33:48 【问题描述】:

我怎样才能打开这样的字典列表..

['a':1, 'b':2, 'c':1, 'd':2]

...变成这样的单个字典:

'a':1, 'b':2, 'c':1, 'd':2

【问题讨论】:

看到这个***.com/questions/2365921/merging-python-dictionaries 是的,虽然它合并到一个列表的字典中。 这是一个列表而不是一个字典:>>> type(['a':1,'b':2]) 考虑到它出现的频率,真的应该有一个衬里。是否有不支持 **d for d in d_list 的原因? 【参考方案1】:

这适用于任何长度的字典:

>>> result = 
>>> for d in L:
...    result.update(d)
... 
>>> result
'a':1,'c':1,'b':2,'d':2

作为comprehension:

# Python >= 2.7
k: v for d in L for k, v in d.items()

# Python < 2.7
dict(pair for d in L for pair in d.items())

【讨论】:

【参考方案2】:

对于 Python 3.3+,有一个 ChainMap collection:

>>> from collections import ChainMap
>>> a = ['a':1,'b':2,'c':1,'d':2]
>>> dict(ChainMap(*a))
'b': 2, 'c': 1, 'a': 1, 'd': 2

另见:

What is the purpose of collections.ChainMap?

【讨论】:

比第一个 dict 理解解决方案慢 10 倍【参考方案3】:

这类似于@delnan,但提供了修改 k/v(键/值)项的选项,我相信它更具可读性:

new_dict = k:v for list_item in list_of_dicts for (k,v) in list_item.items()

例如,替换 k/v 元素如下:

new_dict = str(k).replace(" ","_"):v for list_item in list_of_dicts for (k,v) in list_item.items()

在将 dict 对象拉出列表后,从字典 .items() 生成器中解压缩 k,v 元组

【讨论】:

【参考方案4】:

从PEP 448 解包字典对@dietbuddha 答案的小改进,对我来说,这种方式更具可读性,也是faster as well:

from functools import reduce
result_dict = reduce(lambda a, b: **a, **b, list_of_dicts)

但请记住,这仅适用于 Python 3.5+ 版本。

【讨论】:

【参考方案5】:

对于平面词典,您可以这样做:

from functools import reduce
reduce(lambda a, b: dict(a, **b), list_of_dicts)

【讨论】:

【参考方案6】:
>>> L=['a': 1, 'b': 2, 'c': 1, 'd': 2]    
>>> dict(i.items()[0] for i in L)
'a': 1, 'c': 1, 'b': 2, 'd': 2

注意:'b' 和 'c' 的顺序与您的输出不匹配,因为 dicts 是无序的

如果字典可以有多个键/值

>>> dict(j for i in L for j in i.items())

【讨论】:

如果列表中的任何 dicts 包含多个项目,则失败。 咳*(假设每个字典只包含一个键值对)*咳 啊,首先我发布了一个适用于一般 dicts 的方法,但看起来 OP 不需要它【参考方案7】:
dict1.update( dict2 )

这是不对称的,因为您需要选择如何处理重复的密钥;在这种情况下,dict2 将覆盖dict1。换一种方式。

编辑:啊,抱歉,没看到。

可以在一个表达式中做到这一点:

>>> from itertools import chain
>>> dict( chain( *map( dict.items, theDicts ) ) )
'a': 1, 'c': 1, 'b': 2, 'd': 2

最后这件事不归功于我!

但是,我认为使用简单的 for 循环执行此操作可能更符合 Python 风格(显式 > 隐式、平面 > 嵌套)。 YMMV。

【讨论】:

它是一个列表而不是一个字典:>>> type(['a':1,'b':2]) 【参考方案8】:

您可以使用funcy 库中的join 函数:

from funcy import join
join(list_of_dicts)

【讨论】:

我认为这是一个被低估的答案...【参考方案9】:

如果您不再需要单例字典:

>>> L = ['a':1, 'b':2, 'c':1, 'd':2]
>>> dict(map(dict.popitem, L))
'a': 1, 'b': 2, 'c': 1, 'd': 2

【讨论】:

【参考方案10】:
>>> dictlist = ['a':1,'b':2,'c':1,'d':2, 'e':3]
>>> dict(kv for d in dictlist for kv in d.iteritems())
'a': 1, 'c': 1, 'b': 2, 'e': 3, 'd': 2
>>>

请注意,我在最后一个字典中添加了第二个键/值对,以表明它适用于多个条目。 列表中后面的 dicts 中的键也将覆盖早期 dict 中的相同键。

【讨论】:

以上是关于如何将字典列表合并到单个字典中?的主要内容,如果未能解决你的问题,请参考以下文章

将数据帧字典合并为 1 个单个数据帧

在 2.6 上合并 n 字典和添加值的最快方法 [重复]

在python中合并字典值列表

合并2个不同的列表到字典

合并字典列表以删除所有重复项

python列表中字典按指定相同的键值对合并到一个列表中