2017-02-11 13 views
0

同じキーの辞書の値を追加しようとしています。下の私の例では、「同じ」キーの値を追加しようとしている間、各キーのバージョン番号を削除します。辞書の同じキーの値を読み込んで追加する

item_dict = { 
"item_C_v001" : 100, 
"item_C_v002" : 100, 
"item_A_v001" : 50, 
"item_B_v001" : 75 
} 

私の予想される出力は次のようになります。

"item_C_v" : 200, 
"item_A_v" : 50, 
"item_B_v" : 75 

が、私はitem_dictを印刷しようとした場合の代わりに、私は次のように得た:

"item_C_v" : 100, 
"item_A_v" : 50, 
"item_B_v" : 75 

しかし、私は取り除くしようとした瞬間、それはそうそのitem_C_vは一度読み込まれます。どのように私はそれを出力するために200を得ることができるように、それを '2倍'にすることができますか?

答えて

2

collections.defaultdict(int)を使用して、結果をグループ化し、正規表現などの取得可能なキーの希望する部分で合計することができます。これらの線に沿って何か:

In [1]: from collections import defaultdict 

In [2]: import re 

In [3]: item_dict = { 
    ...: "item_C_v001" : 100, 
    ...: "item_C_v002" : 100, 
    ...: "item_A_v001" : 50, 
    ...: "item_B_v001" : 75 
    ...: } 

In [4]: result = defaultdict(int) 

In [5]: for key, value in item_dict.items(): 
    ...:  result[re.search(r"(\w+?)\d+", key).group(1)] += value 

In [6]: dict(result) 
Out[6]: {'item_A_v': 50, 'item_B_v': 75, 'item_C_v': 200} 

あなたは異なったキーの所望の部分を抽出近づくことができる - str.partition()で:

>>> key = "item_C_v001" 
>>> "".join(key.partition("_v")[:-1]) 
'item_C_v' 

それとも、単にスライスを経由して、文字列の長さならば文字列の末尾の桁数または桁数は一定です。

>>> key = "item_C_v001" 
>>> key[:8] 
'item_C_v' 
>>> key[:-3] 
'item_C_v' 

または、右ストリッピング桁:

>>> import string 
>>> key.rstrip(string.digits) 
'item_C_v' 
+0

クールは、 '使用を認識していませんでした文字列モジュール。多分私はモジュールの使用を減らそうとしています。 'partition'も同じです。私はそのモジュールを持っていたので、 'defaultdict'を組み込むことを試みます。ちょうど私は正規表現の使用にあまり強くはない – dissidia

2

あなたは、元の辞書を反復処理し、キーがすでに存在する場合は、新しい辞書に新しいキーを追加し、元の値に現在の値を追加することができます。

item_dict = { 
"item_C_v001" : 100, 
"item_C_v002" : 100, 
"item_A_v001" : 50, 
"item_B_v001" : 75 
} 

new_dict = {} 

for k, v in item_dict.items(): 
    k_new = k[:-3] 
    new_dict[k_new] = new_dict[k_new] + v if k_new in new_dict.keys() else v 

print (new_dict) 

>>> {'item_A_v': 50, 'item_C_v': 200, 'item_B_v': 75} 
+0

とにかく 'new_dict [k_new]'をさらに改良して '+'を使わないようにすることはできますか?ただそれに興味があります。これは副次的な質問かもしれませんが、 'item_C_v'が2回結合されたことをコードでどのように出力できますか? – dissidia

+0

'new_dict [k_new] = new_dict.get(k_new、0)+ v'で置き換えることができます。' get() 'を使うとデフォルト値を与えることができます。あるいは、 'defaultdict(int)'を使うことができます。そして、 'new_dict [k_new] + = v'を読み込みます。 – AChampion

2

あなたはすべて同様のキーを収集し、すべてのグループの値を合計し、新しい辞書を構築するためにitertools.groupby()を使用することができ、例えば:

>>> import itertools as it 
>>> {gk: sum(item_dict[k] for k in g) for gk, g in it.groupby(item_dict, lambda k: k[:-3])} 
{'item_A_v': 50, 'item_B_v': 75, 'item_C_v': 200} 

@alecxeは、所望の一部を取得するいくつかの方法を説明し上記のキーはkey[-3]を使用します。

ありますが、単純なループで実装し、カウンタを管理することができcountsumの両方を取得するための要求があったが、ここでそれを行うための一つの方法だ:

>>> from collections import deque 
>>> {key: deque(enumerate(it.accumulate(item_dict[k] for k in g), 1), maxlen=1).pop() 
...  for key, g in it.groupby(item_dict, lambda key: key[:-3])} 
{'item_A_v': (1, 50), 'item_B_v': (1, 75), 'item_C_v': (2, 200)} 
関連する問題