Python中的合并字典

Python中的合并字典,python,Python,我有一本字典的清单 input = [{"id":2, "color":"green"}, {"id":3, "color":"red"}, {"id":2, "gender":"male"}, {"id":3, "food":"ice_cream"}, {"id":1, "food":"fish"}] 我的预期产出为 output =[{"id":1, "food":"fish"}, {"id

我有一本字典的清单

input = [{"id":2, "color":"green"}, 
         {"id":3, "color":"red"}, 
         {"id":2, "gender":"male"}, 
         {"id":3, "food":"ice_cream"}, 
         {"id":1, "food":"fish"}]
我的预期产出为

output =[{"id":1, "food":"fish"}, 
         {"id":2, "color":"green", "gender":"male"}, 
         {"id":3, "color":"red", "food":"ice_cream"}]
有没有比多个嵌套for循环更简单的方法呢?

您不需要嵌套循环,只需一个简单的for循环即可:

>>> from collections import defaultdict
>>> output = defaultdict(dict)
>>> for d in input_:
...     output[d['id']].update(d)
...     
>>> output.values()
dict_values([{'id': 2, 'color': 'green', 'gender': 'male'}, {'id': 3, 'color': 'red', 'food': 'ice_cream'}, {'id': 1, 'food': 'fish'}])
现在,您可以按
id
对输出值进行排序

>>> [output[k] for k in sorted(output)]
[{'food': 'fish', 'id': 1},
 {'color': 'green', 'gender': 'male', 'id': 2},
 {'color': 'red', 'food': 'ice_cream', 'id': 3}]
如果数据很大,并且希望避免最后的O(n log n)排序步骤,则可以预先迭代输入以查找ID列表,并保持线性复杂度(这类似于a)

如果你坚持使用
groupby
(效率较低,可读性较差),你可以得到比公认答案中的怪物更清晰的答案。请尝试以下方法:

from itertools import groupby
from operator import itemgetter
from collections import ChainMap
k = itemgetter('id')
output = [dict(ChainMap(*group)) for _, group in groupby(sorted(input_, key=k), k)]

尽管@wim的解决方案是最干净的,但另一种可能性是使用
itertools.groupby

import itertools
import functools
input = [{"id":2, "color":"green"}, {"id":3, "color":"red"}, {"id":2, "gender":"male"}, {"id":3, "food":"ice_cream"}, {"id":1, "food":"fish"}]
new_input = [functools.reduce(lambda x, y:{**x, **y}, list(b)) for _, b in itertools.groupby(sorted(input, key=lambda x:x['id']), key=lambda x:x['id'])]
输出:

[{'id': 1, 'food': 'fish'}, {'id': 2, 'color': 'green', 'gender': 'male'}, {'id': 3, 'color': 'red', 'food': 'ice_cream'}]

如果您想改进某些代码,请尝试。无论哪种方式,如果您想要改进现有的内容,请发布您的代码。