2017-09-21 10 views
0

ここでは、名前キー値をdict値のキーとしてグループ化し、その親キーのキーとしてソース値を数え、カウント値をその値としてカウントしようとしています。Python - dictのリストをキーの値でグループ化し、別のキーの値をdictとしてカウントしますか?

data = [ 
{'name':'Gill', 'source':'foo'}, 
{'name':'Gill', 'source':'foo'}, 
{'name':'Gill', 'source':'foo'}, 
{'name':'Gill', 'source':'bar'}, 
{'name':'Gill', 'source':'bar'}, 
{'name':'Gill', 'source':'bar'}, 
{'name':'Gill', 'source':'bar'}, 
{'name':'Gill', 'source':'bar'}, 
{'name':'Dave', 'source':'foo'}, 
{'name':'Dave', 'source':'foo'}, 
{'name':'Dave', 'source':'foo'}, 
{'name':'Dave', 'source':'foo'}, 
{'name':'Dave', 'source':'egg'}, 
{'name':'Dave', 'source':'egg'}, 
{'name':'Dave', 'source':'egg'}, 
{'name':'Dave', 'source':'egg'}, 
{'name':'Dave', 'source':'egg'}, 
{'name':'Dave', 'source':'egg'}, 
{'name':'Dave', 'source':'egg'} 
] 

以下の出力を得るにはどうすればよいですか?私はそれが1つのライナーで可能かもしれないと思う

{'Gill': {'foo':3, 'bar':5}, 'Dave': {'foo':4, 'egg':7}}

...

+0

このサイトを最初に検索しましたか? – fukanchik

答えて

6

使用itertools.groupbycollecitons.Counterそれぞれの名前に属する源カテゴリー数にそのグループ名で、へ:

from collections import Counter 
from itertools import groupby 

f = lambda x: x['name'] 
dct = {k: Counter(d['source'] for d in g) for k, g in groupby(data, f)} 
print(dct) 
# {'Gill': Counter({'bar': 5, 'foo': 3}), 'Dave': Counter({'egg': 7, 'foo': 4})} 
+0

もちろん、これはデータが '' name ''キーでソートされていることを前提としています。 – vaultah

+0

ありがとう、これは素晴らしいです。しかし、私の実際のデータセットでは、ここで言及していない「名前」と「ソース」よりも多くのキーがあります(私はそれがうまくいくと思いました)。しかし、groupby(data、f)はそれに問題を生じさせるようですが、3番目のキーが導入された場合にこの作業を行う方法がありますが、それを無視していますか? (私はかわいいです) – Slopax

+0

@Slopaxもしあなたが実際にそれを必要としないなら、3番目のキーがどのように問題を作り出すかは分かりません。 –

0

これは明らかに1ライナーではありませんが、単純明快です。任意の数の値に対して機能します。

results = {} 
key = 'name' 
for line in data: 
    tracked_key = line[key] 
    results.setdefault(tracked_key, {}) 
    for k, v in line.iteritems(): 
     if k == key: 
      continue 
     results[tracked_key].setdefault(v, 0) 
     results[tracked_key][v] += 1 
関連する問題