Python求字典键的总和与值的总和

3
首先,这个问题是相关的,但并没有解决我的问题:Python sum dict values based on keys 我有一个像这样的字典:
{
...
"httpXYZ_ACTION1": [10, 0],
"http123_ITEM1": [0.055, 0.0875],
"http456_ACTION1": [0.01824, 0.066667],
"httpABC_ITEM2": [1214.666667, 1244.195833],
"http999_ACTION2": [null, 213],
...
}

我想要的结果是一个像这样的字典
{
...
"_ACTION1": [summed up values for all _ACTION1 on any http]
"_ITEM1": [summed up values for all _ITEM1 on any http]
...
}

我尝试了类似的东西,等等 :-)

sum(filter(None, chain(*[value for key, value in DICT if key.endswith(('_ACTION1', '_ACTION2', '_ITEM1'))])))

显然,它将所有内容总结成一个数字。
5个回答

1
inDict={
"httpXYZ_ACTION1": [10, 0],
"http123_ITEM1": [0.055, 0.0875],
"http456_ACTION1": [0.01824, 0.066667],
"httpABC_ITEM2": [1214.666667, 1244.195833],
"http999_ACTION2": [None, 213],
}
outDictKeys=set('_'+x.split('_')[1] for x in inDict)
outDict={}
for outKey in outDictKeys:
    total=0
    for inKey in inDict:
        if inKey.endswith(outKey):
            total=total+sum([x for x in inDict[inKey] if x is not None])
    outDict[outKey]=total
print (outDict)

在Python 3中运行:

>>> ================================ RESTART ================================
>>> 
{'_ITEM1': 0.1425, '_ITEM2': 2458.8625, '_ACTION2': 213, '_ACTION1': 10.084907}
>>> 

请注意,我将您的null值视为None,它被视为零,即被忽略。如何进行求和取决于您。

1
感谢大家的帮助。这个答案解决了我的问题。其他的答案并不能解决,因为在服务器上无法导入defaultdict。 - Obre1
我的下一个问题是,在这个结构中,我现在应该在哪里将每个键的每个值乘以数字60? - Obre1
将倒数第二行改为“outDict[outKey]=total*60”。这将产生 {'_ACTION2': 12780, '_ACTION1': 605.09442, '_ITEM1': 8.549999999999999, '_ITEM2': 147531.75}。 - Emilio M Bumachar
非常感谢您再次提供的输入!但是!我在这里询问之后自己找到了答案!Python很酷 :-) - Obre1

0
from collections import defaultdict

input = {
  "httpXYZ_ACTION1": [10, 0],
  "http123_ITEM1": [0.055, 0.0875],
  "http456_ACTION1": [0.01824, 0.066667],
  "httpABC_ITEM2": [1214.666667, 1244.195833],
  "http999_ACTION2": [None, 213],
}

output = defaultdict(float)
for k,v in input.items():
  key = '_' + k.partition('_')[2]
  output[key] += sum((float(val) for val in v if isinstance(val, (int,float))))

print(output)

2
为什么要使用partition('_')[2]而不是split('_')[1]?它们显然是等价的,但后者似乎更易于阅读,并且更符合惯用法,因为你只是抛弃下划线。 - reynoldsnlp
我认为原帖作者想要保留下划线。 - NotAnAmbiTurner
@bebop:你说的不正确。partition 正是我们要做的事情。如果你想限制分割次数,split() 需要第二个参数来指定,而 partition 则会自动隐式地完成这一点。在 Python 中,通常使用最清晰的工具来完成任务,在这种情况下,partition 就是为此类用例而创建的。 - gahooa

0

不知道 null 是从哪里来的,但是你可以使用 str.find 提取部分子字符串,并使用 defaultdict 处理重复的键:

from collections import defaultdict
dd = defaultdict(float)

for k, v in d.items():
     dd[k[k.find("_"):]] += sum(v)

print(dd)

defaultdict(<class 'float'>, {'_ITEM1': 0.1425, '_ACTION1': 10.084907, '_ACTION2': 213.0, '_ITEM2': 2458.8625})

如果 null 实际上是 None,则将其过滤掉:

dd[k[k.find("_"):]] += sum(filter(None, v))

或者只保留数字:

 import numbers

 dd[k[k.find("_"):]] + sum(i for i in v if isinstance(i, numbers.Number))

0

这是collections.defaultdict的工作,因为我们需要确保在对sums['_ACTION1']进行+=操作之前存在一个初始化的浮点数,并且通过编程方式确保内置dictionary会导致开销。

#!/usr/bin/env python3
from collections import defaultdict

DICT = {
    "httpXYZ_ACTION1": [10, 0],
    "http123_ITEM1": [0.055, 0.0875],
    "http456_ACTION1": [0.01824, 0.066667],
    "httpABC_ITEM2": [1214.666667, 1244.195833],
    "http999_ACTION2": [None, 213],
}

sums = defaultdict(lambda: 0.)

# with python2 better use
# for (k, l) in DICT.iteritems():
for (k, l) in DICT.items():
    sums[k[k.find("_"):]] += sum(x for x in l if x is not None)

for pair in sums.items():
    print(pair)

输出:

('_ITEM1', 0.1425)
('_ITEM2', 2458.8625)
('_ACTION2', 213.0)
('_ACTION1', 10.084907)

这几乎与我提供的答案完全相同,另外为什么要使用 lambda: 0.,当你可以直接使用 float 呢? - Padraic Cunningham
我认为更具表现力。 - decltype_auto

-1
一个解决方案:
null = 0  # null is invalid in Python unless a variable

data = {
    "httpXYZ_ACTION1": [10, 0],
    "http123_ITEM1": [0.055, 0.0875],
    "http456_ACTION1": [0.075, 0.066667],
    "httpABC_ITEM2": [14.666667, 12.195833],
    "http999_ACTION2": [null, 2],
}

categories = set([c.split('_')[-1] for c in data.keys()])
sums = {k: 0 for k in categories}

for k, v in data.items():
    key = k.split('_')[-1]
    if key in categories:
        sums[key] += 1

print sums

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接