Python:只能在dict中找到某些键,而不是计算总数

时间:2018-04-20 22:29:30

标签: python dictionary

希望我这么想。

我有一份非常大的字典列表。每次根据用户输入选择新号码时,新词典中的键都会改变。这些键来自一个位于旧词典列表相同部分的值(从下面的示例词典中可以得到' id')。

我现在需要使用基于先前用户输入提取的值对字典的非常大的原始列表进行排序。

删除任何无值并从旧词典列表中添加总计。 '字'通过' word4'可以根据以前的用户输入进行更改(我的新词典更改,例如它可能只是word4或者这个小版本中没有列出的完全不同的东西)但是位于旧词典列表中的相同位置。

我觉得我的逻辑在这里很有缺陷。

old_dict = [
    {'name': 'no', 'id':'word', 'value':19},
    {'name': 'asno', 'id':'word2', 'value':27},
    {'name': 'asadsdsano', 'id':'word3', 'value':33},
    {'name': 'nssso', 'id':'word4', 'value':None},
    {'name': 'asnadao', 'id':'word2', 'value':22},
    {'name': 'asadsdsano', 'id':'word3', 'value':27},
    {'name': 'assdadas', 'id':'word4', 'value':11},
    {'name': 'asno', 'id':'word2', 'value':44},
    {'name': 'asadsdsano', 'id':'word3', 'value': None},
    {'name': 'asadsdsano', 'id':'word', 'value':101},
    {'name': 'asaaaadsdsano', 'id':'word2', 'value':101}]

示例输出将是

字:120

word2:150

word3:60

word4:11

3 个答案:

答案 0 :(得分:1)

我想我正确地理解了你:你有一个词典列表,你要按id键的值对列表中的每个字典的value键求和。匹配id密钥。是吗?

有几种方法可以解决这个问题,有些方法可以使用更复杂的工具,但是我只需要使用列表和序列就可以给你一个简单的答案。

输入:

old_dict = [
    {'name': 'no', 'id': 'word', 'value': 19},
    {'name': 'asno', 'id': 'word2', 'value': 27},
    {'name': 'asadsdsano', 'id': 'word3', 'value': 33},
    {'name': 'nssso', 'id': 'word4', 'value': None},
    {'name': 'asnadao', 'id': 'word2', 'value': 22},
    {'name': 'asadsdsano', 'id': 'word3', 'value': 27},
    {'name': 'assdadas', 'id': 'word4', 'value': 11},
    {'name': 'asno', 'id': 'word2', 'value': 44},
    {'name': 'asadsdsano', 'id': 'word3', 'value': None},
    {'name': 'asadsdsano', 'id': 'word', 'value': 101},
    {'name': 'asaaaadsdsano', 'id': 'word2', 'value': 101},
]

代码:

unique_keys = sorted(list(set([x['id'] for x in old_dict])))

new_dict = {}
for key in unique_keys:
    value_sum = sum([x['value'] for x in old_dict if (x['value'] is not None
                                                      and x['id'] == key)])
    new_dict[key] = value_sum

for k, v in new_dict.items():
    print(k, v)

输出:

word 120
word2 194
word3 60
word4 11

答案 1 :(得分:1)

使用itertools中的groupby

>>> from itertools import groupby

请注意groupby()要求对其输入进行排序:

>>> old_dict.sort(key=lambda d: d['id'])

密钥是'id'项目:

>>> g=groupby(old_dict, key=lambda d: d['id'])

使用过滤器删除None值,并使用sum()求和:

>>> {k: sum(filter(None, (x['value'] for x in v))) for k, v in g}
{'word': 120, 'word2': 194, 'word3': 60, 'word4': 11}

答案 2 :(得分:1)

选项1:defaultdict

您可以将collections.defaultdictfor循环一起使用。

from collections import defaultdict

d = defaultdict(int)

for item in old_dict:
    val = item['value']
    if val:
        d[item['id']] += val

结果:

defaultdict(int, {'word': 120, 'word2': 194, 'word3': 60, 'word4': 11})

选项2:pandas

如果您愿意使用第三方库,pandas会接受字典列表:

import pandas as pd

d = pd.DataFrame(old_dict).groupby('id')['value'].sum().to_dict()

结果:

{'word': 120.0, 'word2': 194.0, 'word3': 60.0, 'word4': 11.0}