2017-02-11 67 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

您可以使用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

酷,不知道用的'字符串「模塊。也許我試圖減少任何模塊的使用。 「分區」也一樣。因爲我有那個模塊,所以會嘗試使用'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'已經被兩次組合? – 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)} 
相關問題