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

时间:2014-04-02 04:54:10

标签: python dictionary python-2.6

我在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}]

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

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

我一直在搜索和尝试不同的东西,开启和关闭几天,我终于放弃了问。我尝试了各种版本的max,key,lambda等,但我在这里找到的所有线程似乎都不是我想要的。

提前致谢!

2 个答案:

答案 0 :(得分:1)

这是一个计划。它假设您不关心dicts订单,但您可以修改它来关注。

让我们看看我们拥有的东西。首先,从列表产生的dict到来并不重要,所以我们可以将它们链接起来。其次,从具有相同形状的每组dicts中,我们只选择一个。看起来我们需要按形状对所有dicts进行分组,然后为每个组选择一个优先级最高的dict。

显而易见的方法是与collections.defaultdict分组,然后在列表理解中使用max来选择每个组中的最佳字典。稍微有点棘手的是首先按形状和减去优先级排序,按形状分组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]

答案 1 :(得分:1)

只需使用一个新的字典,其中合并的列表按优先级排序,以便在合并列表中保存每个字典:

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'}]

由于这是具有唯一键的字典,因此给定形状的最后一项将替换具有相同形状的较早项。由于项目按优先级排序,因此{'shape': 'square', 'color': 'red', 'priority': 2}字典中的res会被{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()