1

我在 Python 列表中有多个字典,如下所示

[{"color": "#CC3", "values": {"y": 83, "x": 9}, "key": 105},
 {"color": "#CC3", "values": {"y": 123, "x": 10}, "key": 105},
 {"color": "#FF9", "values": {"y": 96, "x": 11}, "key": 106},
 {"color": "#33F", "values": {"y": 80, "x": 12}, "key": 104},
 {"color": "#CC3", "values": {"y": 117, "x": 13}, "key": 105},
 {"color": "#CC3", "values": {"y": 115, "x": 14}, "key": 105},
 {"color": "#CC3", "values": {"y": 102, "x": 15}, "key": 105},
 {"color": "#FF9", "values": {"y": 111, "x": 16}, "key": 106},
 {"color": "#FF9", "values": {"y": 33, "x": 17}, "key": 106}]

在上面包含字典的列表中,有一些键称为“键”,其值相同,例如 105、106 等,在这些字典中,“值”的值各不相同,例如"values": {"y": 83, "x": 9}105 "values": {"y": 117, "x": 13}

我想在一个字典中添加并带来相同“key=xxx”字典的值

例如,对于具有 key=105 的字典,我想聚合“值”:[{"y": 83, "x": 9},{"y": 117, "x": 13}] 在这样的列表中说

最终合并输出应保留上述原始结构

[{"color"="...","values"=[{...},{...}],"key"="..."},....]

实现这一目标的最佳方法是什么?

4

4 回答 4

4

您可以使用collections.defaultdict.

如果您提供list给它,它会在访问新密钥时自动创建空列表。

from collections import defaultdict

a = [{"color": "#CC3", "values": {"y": 83, "x": 9}, "key": 105}, {"color": "#CC3", "values": {"y": 123, "x": 10}, "key": 105}, {"color": "#FF9", "values": {"y": 96, "x": 11}, "key": 106}, {"color": "#33F", "values": {"y": 80, "x": 12}, "key": 104}, {"color": "#CC3", "values": {"y": 117, "x": 13}, "key": 105}, {"color": "#CC3", "values": {"y": 115, "x": 14}, "key": 105}, {"color": "#CC3", "values": {"y": 102, "x": 15}, "key": 105}, {"color": "#FF9", "values": {"y": 111, "x": 16}, "key": 106}, {"color": "#FF9", "values": {"y": 33, "x": 17}, "key": 106}]

result = defaultdict(list)

for d in a:
    result[d['key']].append(d['values'])

dict(result)就是现在:

{104: [{'y': 80, 'x': 12}],
 105: [{'y': 83, 'x': 9}, {'y': 123, 'x': 10}, {'y': 117, 'x': 13}, {'y': 115, 'x': 14}, {'y': 102, 'x': 15}],
 106: [{'y': 96, 'x': 11}, {'y': 111, 'x': 16}, {'y': 33, 'x': 17}]}
于 2012-10-08T13:10:48.773 回答
1
data=[{"color": "#CC3", "values": {"y": 83, "x": 9}, "key": 105}, {"color": "#CC3", "values": {"y": 123, "x": 10}, "key": 105}, {"color": "#FF9", "values": {"y": 96, "x": 11}, "key": 106}, {"color": "#33F", "values": {"y": 80, "x": 12}, "key": 104}, {"color": "#CC3", "values": {"y": 117, "x": 13}, "key": 105}, {"color": "#CC3", "values": {"y": 115, "x": 14}, "key": 105}, {"color": "#CC3", "values": {"y": 102, "x": 15}, "key": 105}, {"color": "#FF9", "values": {"y": 111, "x": 16}, "key": 106}, {"color": "#FF9", "values": {"y": 33, "x": 17}, "key": 106}]

databykey={}   #make a new dictionary
for l in data:   # for each item in the list
 if l['key'] in databykey: databykey[l['key']]['values'].append(l['values'])
 else: databykey[l['key']]={'color':l['color'], 'values':[l['values']]}
 # if the item's key is already in the dictionary, add its values to the list
 # else, add the key to the dictionary with the color and the first value

databykey就是现在

{104: {'color': '#33F', 'values': [{'y': 80, 'x': 12}]},
 105: {'color': '#CC3','values': [{'y': 83, 'x': 9}, {'y': 123, 'x': 10}, {'y': 117, 'x': 13}, {'y': 115, 'x': 14}, {'y': 102, 'x': 15}]},
 106: {'color': '#FF9', 'values': [{'y': 96,'x': 11}, {'y': 111, 'x': 16}, {'y': 33, 'x': 17}]}}
于 2012-10-08T15:28:02.293 回答
0

尝试这样的事情:

dicts = [{...}, {...}]

def get_values(key):
    return [d["values"] for d in dicts if d["key"] == key]

values_for_105 = get_values(105)

对于您的示例values_for_105

[{'y': 83, 'x': 9}, 
 {'y': 123, 'x': 10}, 
 {'y': 117, 'x': 13}, 
 {'y': 115, 'x': 14}, 
 {'y': 102, 'x': 15}]
于 2012-10-08T13:08:51.093 回答
0

如果您只想根据键对元素进行分组,则使用该itertools.groupby函数并直接执行此操作,而无需创建以下实例的混乱开销defaultdict

import itertools

def key_func(elem):
    return elem["key"]

[{k:list(elem)} for k, elem in itertools.groupby(list_of_dicts, key_func)]

这会产生:

[{100: [{'key': 100, 'x': 10, 'y': 20}, {'key': 100, 'x': 5, 'y': 3.4}]},
 {200: [{'key': 200, 'x': 44, 'y': 3.14}, {'key': 200, 'x': -44, 'y': 3.14}]}]

(来自我下面的测试示例)。

这是一种更强大的处理方式,因为 (a) 它将原始键留在了 dicts 中(如果需要,您可以选择忽略它们,但您不受删除它们的限制..因此损耗较小), (b) 您可以进行分组操作/聚合(下面的示例)。

假设您的初始字典列表被调用list_of_dicts,并且您想要一个新的字典列表作为输出,其中只有xy条目通过求和它们来聚合。

[
 reduce(
        lambda a,b: {"key":a["key"], "x":a["x"]+b["x"], "y":a["y"]+b["y"]},
        list(elem)
       ) 
 for k, elem in itertools.groupby(list_of_dicts, key_func)
]

如果我使用以下测试输入运行:

list_of_dicts = [
                 {"key":100, "x":10, "y":20}, 
                 {"key":100, "x":5, "y":3.4}, 
                 {"key":200, "x":44, "y":3.14}, 
                 {"key":200, "x":-44, "y":3.14}
                ]

然后我得到以下结果:

print [reduce(lambda a,b: {"key":a["key"], "x":a["x"]+b["x"], "y":a["y"]+b["y"]}, list(elem)) for k, elem in itertools.groupby(list_of_dicts, key_func)]

[{'key': 100, 'x': 15, 'y': 23.4}, {'key': 200, 'x': 0, 'y': 6.28}]
于 2012-10-08T13:10:04.120 回答