2016-05-02 11 views
1

私は(しかし、はるかに長い)などの辞書を持っている:サム値(パイソン)

codes = { 
    '113110': 7, '113310': 1, '213111': 1, 
    '213112': 3, '236115': 2, '236220': 1, 
    '238190': 1, '238330': 1, '238990': 2, 
    '311612': 1, '321214': 1,  } 

私は最初の2桁によってグループ化されたすべてのキーの合計値を知りたいです。だから、 '11'は8でなければなりません。しかし、次のようにチェックすると、キーのどこにでも'11 'が現れます。

group_11 = sum([ v for k,v in codes.items() if '11' in k]) 
# Returns 15 instead of 8 

私はstartswithを使用してみましたが、私はそれが、この文脈でどのように動作するかわかりません。これを好きではない:

group_11 = sum([ v for k,v in codes.items() if any(k.startswith('11')]) 

私は、チェック対象の20グループがありますが、私はグループが将来的に変更される可能性として、最初のx文字でグループ化キーの任意のセットを合計することができるようにしたいです。

あなたがソートする itertools.groupbyを使用( groupbyが正しく動作するためにソートが重要である)とグループあなた dictのアイテムを最初の二つのキー文字で、各グループの値を合計することができ

答えて

3

from itertools import groupby 

d = { 
    k: sum(item[1] for item in g) 
    for k, g in groupby(sorted(codes.items()), key=lambda item: item[0][:2]) 
} 

d 
{'11': 8, '32': 1, '31': 1, '21': 4, '23': 7} 
0

あなたはcodesのすべての商品をCounterに変換してまとめてください:

from collections import Counter 

codes = { 
    '113110': 7, '113310': 1, '213111': 1, 
    '213112': 3, '236115': 2, '236220': 1, 
    '238190': 1, '238330': 1, '238990': 2, 
    '311612': 1, '321214': 1 
} 

sum((Counter({k[:2]: v}) for k, v in codes.iteritems()), Counter()) # Counter({'11': 8, '23': 7, '21': 4, '32': 1, '31': 1})