python sum dict键和sum dict值

时间:2015-11-19 18:20:34

标签: python dictionary

首先,这个问题是相关的,但没有解决我的问题 Python sum dict values based on keys

我有像这样的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": [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 个答案:

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

不知道import itertools def all_merges(a, b): # object guaranteed not to be in either input list sentinel = object() merged_length = len(a) + len(b) for a_positions in itertools.combinations(xrange(merged_length), len(a)): merged = [sentinel] * merged_length # Place the elements of a in their chosen positions. for pos, a_elem in zip(a_positions, a): merged[pos] = a_elem # Place the elements of b in the positions not taken. b_iter = iter(b) for pos in xrange(merged_length): if merged[pos] is sentinel: merged[pos] = next(b_iter) yield merged 来自何处,但您可以使用str.find提取部分子字符串,使用null来处理重复键:

defaultdict

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

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

或者只保留数字:

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

答案 3 :(得分:0)

这是collections.defaultdict的工作,因为我们需要注意这一点,例如在sums ['_ ACTION1']存在一个初始化的浮点数,然后我们可以+ = sth到它,并以编程方式确保内置的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)

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