在python中基于其他字典值创建多个字典

时间:2011-03-04 12:14:42

标签: python dictionary

我有一个包含许多词典的列表。每个字典代表我的应用程序中发生的更改。 “更改”字典具有以下条目:

userid: The user ID for a user
ctype: A reference to a change type in my application
score: A score

ctype可以是大约12种不同的字符串之一,包括“删除”,“新”,“编辑”等。以下是其中一个“更改”词典的示例:

{'userid':2, 'score':10, 'ctype':'edit'}

我的问题是,如何在这个庞大的词典列表中创建一个字典来汇总每个用户的所有更改类型?我想添加每个更改字典的分数以创建总分,并将每个ctype实例添加到一起以获取每个实例的计数。目标是有一个字典列表,每个字典看起来像这样:

{'userid':2, 'score':325, 'deletion':2, 'new':4, 'edit':9}

我一直试图解决这个问题,但我对python很新,我不知道如何计算实际的更改类型。得到我的另一部分是如何引用基于'userid'的字典。如果有人能够提出答案,我相信所有这些对我来说都会变得非常明显。我感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

这里聚合数据的关键是拥有一个字典,其中每个键都是userid,每个条目都是与该用户ID相关的数据。

final_data = {}
for entry in data:
    userid = entry["userid"]
    if userid not in final_data:
        final_data[userid] = {"userid": userid, "score": 0} 
    final_data[userid]["score"] += entry["score"]
    if not entry["ctype"] in final_data[userid]:
        final_data[userid][entry["ctype"]] = 1
    else:
        final_data[userid][entry["ctype"]] += 1

如果您希望将结果作为词典列表,请使用final_data.values()

答案 1 :(得分:0)

你有吗

(模拟不是真正的python。)

{userid : {score : 1, ctype : ''}}

您可以将dict作为值嵌套在python词典中。

答案 2 :(得分:0)

要根据userid索引词典,您可以使用词典词典:

from collections import defaultdict

dict1 = {'userid': 1, 'score': 10, 'ctype': 'edit'}
dict2 = {'userid': 2, 'score': 13, 'ctype': 'other'}
dict3 = {'userid': 1, 'score': 1, 'ctype': 'edit'}
list_of_dicts = [dict1, dict2, dict3]

user_dict = defaultdict(lambda: defaultdict(int))
for d in list_of_dicts:
    userid = d['userid']
    user_dict[userid]['score'] += d['score']
    user_dict[userid][d['ctype']] += 1


# user_dict is now
# defaultdict(<function <lambda> at 0x02A7DF30>,
#  {1: defaultdict(<type 'int'>, {'edit': 2, 'score': 11}),
#   2: defaultdict(<type 'int'>, {'score': 13, 'other': 1})})

在示例中,我使用defaultdict来避免在每次迭代时检查密钥d['ctype']是否存在。

答案 3 :(得分:0)

看起来像这样:

change_types = ['deletion', 'new', 'edit', ...]
user_changes = {}
for change in change_list:
    userid = change['userid']
    if not userid in user_changes:
        aggregate = {}
        aggregate['score'] = 0
        for c in change_types:
            aggregate[c] = 0
        aggregate['userid'] = userid
        user_changes[userid] = aggregate
    else:
        aggregate = user_changes[userid]

    change_type = change['ctype']
    aggregate[change_type] = aggregate[change_type] + 1
    aggregate['score'] = aggregate['score'] + change['score']

实际上为聚合创建一个类是个好主意。