Python sum dict values based on keys

后端 未结 3 1590
遥遥无期
遥遥无期 2021-01-15 14:11

How to sum values from dict where values are string. I mean how to sum values where multiply key is same in dictionary.

dict

values = [
    {
                


        
相关标签:
3条回答
  • 2021-01-15 14:20

    Specific solution, with no attempt at cleverness:

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

    And a slightly more generic solution:

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

    Now someone will certainly chime in with a much more clever solution involving itertools...

    0 讨论(0)
  • 2021-01-15 14:28

    Here's a solution that uses a temporary dict with keys based on the input dict's key value pairs where the values are of type 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()
    

    Or if you want to use 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, [])
    
    0 讨论(0)
  • 2021-01-15 14:44

    This is a simple and specific solution, I am sure there are more general and cleverer ones. :)

    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
    

    gives

    [{'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'}]
    
    0 讨论(0)
提交回复
热议问题