如何对值为字符串的dict中的值求和。我的意思是如何对字典中乘法键相同的值求和。
values = [
{
"rashod": 0,
"prihod": 230.0,
"prod_name": "r",
"prod_hola": "t"
},
{
"rashod": 0,
"prihod": 230.0,
"prod_name": "r",
"prod_hola": "t"
},
{
"rashod": 0.0,
"prihod": 0,
"prod_name": "c",
"prod_hola": "f"
},
{
"rashod": 0,
"prihod": 100.0,
"prod_name": "c",
"prod_hola": "f"
},
{
"rashod": 0.0,
"prihod": 0,
"prod_name": "a",
"prod_hola": "b"
},
{
"rashod": 0,
"prihod": 1500.0,
"prod_name": "a",
"prod_hola": "b"
}]
dictf = reduce(lambda x, y: dict((k, v + y[k]) for k, v in x.iteritems()), values)
print dictf
但这总结了dict中的所有值,输出如下:
{'rashod': 1930.0, 'prihod': -17020.0, 'prod_name': 'abcfrtabcfrtabcfrt'}
我想要的是这样输出:
[{'rashod': 1930.0, 'prihod': -17020.0, 'prod_name': 'a','prod_hola':'b},
{'rashod': 1930.0, 'prihod': -17020.0, 'prod_name': 'c','prod_hola':'f},
{'rashod': 1930.0, 'prihod': -17020.0, 'prod_name': 'r','prod_hola':'t},]
答案 0 :(得分:3)
具体解决方案,没有尝试聪明:
def regroup(values):
groups = dict()
for d in values:
key = (d["prod_name"], d["prod_hola"])
if key in groups:
group = groups[key]
group["rashod"] += d["rashod"]
group["prihod"] += d["prihod"]
else:
groups[key] = d.copy()
return list(groups.values())
稍微更通用的解决方案:
def generic_regroup(values, keys):
groups = dict()
valkeys = [k for k in values[0] if k not in key]
for d in values:
key = tuple(d[k] for k in keys)
if key in groups:
group = groups[key]
for k in valkeys:
group[k] += d[k]
else:
groups[key] = d.copy()
return list(groups.values())
results = generic_regroup(values, ("prod_name", "prod_hola"))
现在有人肯定会使用涉及itertools的更聪明的解决方案......
答案 1 :(得分:1)
这是一个简单而具体的解决方案,我相信有更普遍和更聪明的解决方案。 :)
from collections import defaultdict
pr = defaultdict(float)
ra = defaultdict(float)
for el in values:
combi = (el['prod_name'], el['prod_hola'])
pr[combi] += el['prihod']
ra[combi] += el['rashod']
results = [dict(rashod=r, prihod=p, \
prod_name=nh[0], prod_hola=nh[1]) \
for r,p,nh in zip(ra.values(), pr.values(), pr)]
print results
给出
[{'rashod': 0.0, 'prihod': 100.0, 'prod_name': 'c', 'prod_hola': 'f'},
{'rashod': 0.0, 'prihod': 1500.0, 'prod_name': 'a', 'prod_hola': 'b'},
{'rashod': 0.0, 'prihod': 460.0, 'prod_name': 'r', 'prod_hola': 't'}]
答案 2 :(得分:0)
这是一个使用临时dict
的解决方案,其中包含基于输入dict
的键值对的键,其值为str
类型:
def get_key(d):
return {k: v for k, v in d.items() if isinstance(v, str)}
def sum_dicts(x, y):
summed = {k: x.get(k, 0) + y[k] for k, v in y.items() if not isinstance(v, str)}
summed.update(get_key(y))
return summed
result = {}
for value in values:
key = json.dumps(get_key(value))
result[key] = sum_dicts(result.get(key, {}), value)
print result.values()
或者如果您想使用reduce()
:
def dict_sum_reducer(items, new):
new_items = map(lambda x: sum_dicts(x, new) if get_key(x) == get_key(new) else x, items)
if new_items == items:
new_items.append(new)
return new_items
print reduce(dict_sum_reducer, values, [])