Python3:获取字典列表中特定键的值之和

时间:2020-09-30 15:46:34

标签: json python-3.x list

我偶然发现了一个我不知道的简单问题。
我有一个保存在json文件中的对象列表。转换成Python后,它们会给我这样的信息:

data = [
    {"id": 1, "value": 3},
    {"id": 2, "value": 1},
    {"id": 3, "value": 5},
    {"id": 1, "value": 1},
    {"id": 1, "value": 2},
    {"id": 3, "value": 2},
    {"id": 1, "value": 3}
]

我正在尝试每个唯一的“ id”只有一个对象/词典。换句话说,我正在尝试获得以下结果:

[{"id": 1, "value": 9}, {"id": 2, "value": 1}, {"id": 3, "value": 7}]

很显然,我可以做很长一段路:

foo = list(set([item["id"] for item in data]))

newList = []
for i in foo:
    bar = {"id": i, "value": 0}
    for x in data:
        if x['id'] == i:
            bar['value'] += x['value']

    newList.append(bar)

但是,我担心这种三层嵌套的循环可能会使大型数据集大大减慢该过程。

我对sum(d.values())很熟悉,并且在collection's Counters上看到了这个问题,但是在我的情况下,这些方法不起作用。

有什么想法可以得到想要的结果吗?

1 个答案:

答案 0 :(得分:1)

Pandas来营救!

首先,根据您的数据创建一个数据框

df = pd.DataFrame(data)
print(df)
Output:
   id  value
0   1      3
1   2      1
2   3      5
3   1      1
4   1      2
5   3      2
6   1      3

然后,group by ID和sum

result = df.groupby("id").sum()
print(result)
Output:
    value
id       
1       9
2       1
3       7

然后将其转换为所需的列表:

new_list = [{"id": elemid, "value": val.value} for elemid, val in result.iterrows()]
print(new_list)
# Output: [{'id': 1, 'value': 9}, {'id': 2, 'value': 1}, {'id': 3, 'value': 7}]

或者,您可以改善现有方式:

data = [
    {"id": 1, "value": 3},
    {"id": 2, "value": 1},
    {"id": 3, "value": 5},
    {"id": 1, "value": 1},
    {"id": 1, "value": 2},
    {"id": 3, "value": 2},
    {"id": 1, "value": 3}
]

new_data = {}
for elem in data:
    elemid = elem["id"]
    value = elem["value"]
    new_data[elemid] = new_data.get(elemid, 0) + value

print(new_data)
# Output: {1: 9, 2: 1, 3: 7}

然后,将其转换为所需的列表:

new_list = [{"id": key, "value": value} for key, value in new_data.items()]
print(new_list)
# Output: [{'id': 1, 'value': 9}, {'id': 2, 'value': 1}, {'id': 3, 'value': 7}]