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

Python 在字典中读取并添加相同键的值,python,dictionary,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_C_v" :

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

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_C_v" : 100,
"item_A_v" : 50,
"item_B_v" : 75
但在我试图脱掉衣服的那一刻,似乎
item\u C\u v
被读取了一次。如何将其读取“两次”,以便获得
200
作为其输出?

您可以使用a对结果进行分组,并将结果与键的所需部分相加,例如,使用正则表达式。大致如下:

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}

您可以使用以下方法以不同的方式提取关键点的所需部分:

或者,简单地通过切片,如果数字前的子字符串长度或字符串末尾的位数是恒定的:

>>> key = "item_C_v001"
>>> key[:8]
'item_C_v'
>>> key[:-3]
'item_C_v'
或者,通过右键剥离数字:

>>> import string
>>> key.rstrip(string.digits)
'item_C_v'
您可以使用组合键将结果分组并按键的所需部分求和,例如,可以使用正则表达式获得该部分。大致如下:

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}

您可以使用以下方法以不同的方式提取关键点的所需部分:

或者,简单地通过切片,如果数字前的子字符串长度或字符串末尾的位数是恒定的:

>>> key = "item_C_v001"
>>> key[:8]
'item_C_v'
>>> key[:-3]
'item_C_v'
或者,通过右键剥离数字:

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

您可以迭代原始字典并将新的键附加到新字典中,如果键已经存在,则将当前值添加到原始值中

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}

您可以迭代原始字典并将新的键附加到新字典中,如果键已经存在,则将当前值添加到原始值中

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}

您可以使用
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描述了几种获取所需密钥部分的方法,上面使用了
密钥[-3]

有一个请求同时获取
计数
总和
,您可以在一个简单的循环中实现并管理计数器,但这里有一种方法:

>>> 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)}

您可以使用
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描述了几种获取所需密钥部分的方法,上面使用了
密钥[-3]

有一个请求同时获取
计数
总和
,您可以在一个简单的循环中实现并管理计数器,但这里有一种方法:

>>> 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)}

我是否可以进一步改进
new\u dict[k\u new]
,使其不使用“+”?只是好奇而已。这可能是一个附带问题,但如何在代码中输出已组合两次的
item_C_v
?您可以将其替换为
new_dict[k_new]=new_dict.get(k_new,0)+v
,使用
get()
可以提供默认值。或者您可以使用
defaultdict(int)
,然后该行将读取
new\u dict[k\u new]+=v
是否还有其他方法可以进一步细化
new\u dict[k\u new]
,以便不使用“+”?只是好奇而已。这可能是一个附带问题,但如何在代码中输出已组合两次的
item_C_v
?您可以将其替换为
new_dict[k_new]=new_dict.get(k_new,0)+v
,使用
get()
可以提供默认值。或者您可以使用
defaultdict(int)
,然后该行将读取
new\u dict[k\u new]+=v
Cool,但不知道使用
string
模块。也许我正试图减少任何模块的使用。
分区也是如此。我将尝试使用
defaultdict
,因为我有这个模块。只是我在使用regexCool方面不是很强,没有意识到使用
string
模块。也许我正试图减少任何模块的使用。
分区也是如此。我将尝试使用
defaultdict
,因为我有这个模块。只是我不是很擅长使用正则表达式