多字典 - 对于所有相同的密钥,请进行一些聚合

时间:2013-11-02 08:59:24

标签: python for-loop file-io dictionary

以下是1个python脚本的输出:

 { 12: {'@': False, '#': False, 'word': 'good#1st#time#will',    'longword': True, 'title': False, 'charcount': 18, 'uppercase': False, 'stop': False, 'sscore': False, 'url': False, '!!!': False} }
 { 12: {'@': False, '#': False, 'word': 'be', 'longword': False, 'title': False,   'charcount': 2, 'uppercase': False, 'stop': True, 'sscore': False, 'url': False, '!!!': False} }
 { 12: {'@': False, '#': False, 'word': 'going', 'longword': False, 'title': False, 'charcount': 5, 'uppercase': False, 'stop': False, 'sscore': False, 'url': False, '!!!': False} }
 { 13: {'@': False, '#': False, 'word': 'back#', 'longword': False, 'title': False, 'charcount': 5, 'uppercase': False, 'stop': False, 'sscore': False, 'url': False, '!!!': False} }
 { 13: {'@': False, '#': False, 'word': 'http://instagr.am/p/rx9939civ8/\xc2\xa0', 'longword': True, 'title': False, 'charcount': 33, 'uppercase': False, 'stop': False, 'sscore': False, 'url': True, '!!!': False} }

在另一个python脚本中,上面的内容被视为输入。以上所有代码都是不同的字典是1个脚本的输出,但在另一个脚本中,我想做一个'charcount'或longword = True的计数,这些多字典具有相同的键,所以输出看起来像:

 { 12: {'longword': 1 ,'charcount': 25} }
 { 13: {'longword': 1 ,'charcount': 38} }


我的数据集不对它们进行分组,但输出单个词典,其中12为键,13为键。我的代码应该能够找到所有相同的密钥,因为我有一个大数据集并执行上述聚合
这是我的代码,它将上面的内容作为多字典,但我不明白我将如何进行聚合。

 dicts = {}
 for line in sys.stdin:
    d = ast.literal_eval(line)
    for k,v in d.items():
       dicts.setdefault(k, []).append(v)
       for key,val in v.items():

这是我到目前为止的代码。

3 个答案:

答案 0 :(得分:1)

您不需要迭代v,因为您感兴趣的键是固定的。

import ast
import sys

dicts = {}
for line in sys.stdin:
    d = ast.literal_eval(line)
    for k, v in d.items():
        inner_dict = dicts.setdefault(k, {})
        inner_dict['longword'] = inner_dict.get('longword', 0) + v.get('longword', 0)
        inner_dict['charcount'] = inner_dict.get('charcount', 0) + v.get('charcount', 0)

print dicts

dicts成为:

{12: {'charcount': 25, 'longword': 1},
 13: {'charcount': 38, 'longword': 1}}

答案 1 :(得分:1)

使用collections.default

import sys
import ast
from collections import defaultdict
my_dict = defaultdict(lambda: {'longword':0, 'charcount':0})
for line in sys.stdin:
    d = ast.literal_eval(line)
    key = list(d)[0]
    my_dict[key] = {k: d[key][k]+v for k, v in my_dict[key].items()}
print my_dict   

<强>输出:

defaultdict(<function <lambda> at 0xb7466a04>,
 {12: {'charcount': 25, 'longword': 1},
  13: {'charcount': 38, 'longword': 1}})

使用collectons.Countercollections.defaultdict的另一种解决方案:

import sys
import ast
from collections import defaultdict, Counter
keys = ['longword', 'charcount']
my_dict = defaultdict(Counter)
for line in sys.stdin:
    d = ast.literal_eval(line)
    key = list(d)[0]
    my_dict[key].update(**{k:d[key][k] for k in keys})
print my_dict    

<强>输出:

defaultdict(<class 'collections.Counter'>,
{12: Counter({'charcount': 25, 'longword': 1}),
 13: Counter({'charcount': 38, 'longword': 1})})

答案 2 :(得分:1)

直截了当的事情

from collections import defaultdict

dicts =[ { 12: {'@': False, '#': False, 'word': 'good#1st#time#will',    'longword': True, 'title': False, 'charcount': 18, 'uppercase': False, 'stop': False, 'sscore': False, 'url': False, '!!!': False} },
     { 12: {'@': False, '#': False, 'word': 'be', 'longword': False, 'title': False,   'charcount': 2, 'uppercase': False, 'stop': True, 'sscore': False, 'url': False, '!!!': False} },
     { 13: {'@': False, '#': False, 'word': 'back#', 'longword': False, 'title': False, 'charcount': 5, 'uppercase': False, 'stop': False, 'sscore': False, 'url': False, '!!!': False} },
     { 13: {'@': False, '#': False, 'word': 'http://instagr.am/p/rx9939civ8/\xc2\xa0', 'longword': True, 'title': False, 'charcount': 33, 'uppercase': False, 'stop': False, 'sscore': False, 'url': True, '!!!': False} },
     { 12: {'@': False, '#': False, 'word': 'going', 'longword': False, 'title': False, 'charcount': 5, 'uppercase': False, 'stop': False, 'sscore': False, 'url': False, '!!!': False} }
]

result = defaultdict(lambda: defaultdict(int))

for d in dicts:
    for k, v in d.items():
        result[k]['longword'] += v.get('longword', 0)
        result[k]['charcount'] += v.get('charcount', 0)

for k, v in result.items():
    print k, dict(v)
#12 {'charcount': 25, 'longword': 1}
#13 {'charcount': 38, 'longword': 1}