繁体   English   中英

合并基于一个键/值对的python词典列表?

[英]Merging a list of dictionaries in python based on one key/value pair?

我在python 2.6中有两个字典列表,我想根据对应于另一个键的一个键的最大值合并它们。 列表如下:

[{shape: square, color: red, priority: 2},
{shape: circle, color: blue, priority: 2},
{shape: triangle, color: green, priority: 2}]

[{shape: square, color: green, priority: 3},
{shape: circle, color: red, priority: 1}]

我试图得到这样的输出:

[{shape: square, color: green, priority: 3},
{shape: circle, color: blue, priority: 2},
{shape: triangle, color: green, priority: 2}]

(项目的顺序并不重要。)

换句话说,我想遍历两个列表,并获取每个列表项的“颜色”,“形状”和“优先级”的字典,其中对于每个“形状”值,“优先级”的值最高)

几天以来,我一直在搜索和尝试SO上的其他事情,而我终于同意了。 我尝试了各种版本的max,key,lambda等,但是在这里可以找到的所有线程似乎都不是我想要的。

提前致谢!

这是一个计划。 假定您不关心命令顺序,但可以对其进行修改以关心命令。

让我们看看我们有什么。 首先,结果字典来自哪个列表并不重要,因此我们可以将它们链接起来。 其次,从形状相同的每组字典中,我们只选择一个。 看起来我们需要按形状对所有字典进行分组,然后为每个组选择优先级最高的字典。

最明显的方法是将collections.defaultdict分组,然后在列表推导中使用max选择每个组中的最佳dict。 稍微棘手的是itertools.groupby形状和优先级排序,然后按itertools.groupby按形状分组,然后从每个组中选择第一个元素:

from itertools import chain, groupby 

sorted_dicts = sorted(chain(list1, list2), 
                      key=lambda d: (d['shape'], -d['priority'])) 
groups = groupby(sorted_dicts, key=lambda d: d['shape'])
merged = [next(g) for _, g in groups]

只需对合并列表使用按优先级排序的新字典,即可将每个字典保存在合并列表中:

li1=[{'shape': 'square', 'color': 'red', 'priority': 2},
{'shape': 'circle', 'color': 'blue', 'priority': 2},
{'shape': 'triangle', 'color': 'green', 'priority': 2}]

li2=[{'shape': 'square', 'color': 'green', 'priority': 3},
{'shape': 'circle', 'color': 'red', 'priority': 1}]

res={}
for di in sorted(li1+li2, key=lambda d: d['priority']):
    res[di['shape']]=di

print res.values()  

打印:

[{'color': 'blue', 'priority': 2, 'shape': 'circle'}, 
 {'color': 'green', 'priority': 3, 'shape': 'square'}, 
 {'color': 'green', 'priority': 2, 'shape': 'triangle'}]

由于这是具有唯一键的字典,因此给定形状的最后一个项目将替换具有相同形状的较早的项目。 由于项目按优先级排序,因此res字典中的{'shape': 'square', 'color': 'red', 'priority': 2}{shape: square, color: green, priority: 3}替换{shape: square, color: green, priority: 3}因为3> 2,依此类推。

因此,您可以在Python 2.7+中的一行中完成所有操作:

{di['shape']:di for di in sorted(li1+li2, key=lambda d: d['priority'])}.values()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM