在字典中读取并添加相同键的值

时间:2017-02-11 00:42:59

标签: python dictionary

我正在尝试添加相同键的字典值。在下面的示例中,我在尝试添加“相同”键的值时删除了每个键的版本编号。

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作为它的输出?

3 个答案:

答案 0 :(得分: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'

答案 1 :(得分: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}

答案 2 :(得分: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)}