sum list of dictionary values

后端 未结 7 2234
情深已故
情深已故 2020-12-20 21:23

I have a list of dictionary in this form :

[
{\'signal_8\': 1, \'signal_1\': 7, \'signal_10\': 5, \'signal_5\': 2, \'signal_2\': 5, \'signal_6\': 3, \'signa         


        
相关标签:
7条回答
  • 2020-12-20 22:05

    Similar to daveruinseverything's answer, I'd solve this with a Counter, but make use of its update method.

    Let signals be your list of dicts.

    >>> from collections import Counter
    >>> c = Counter()
    >>> for d in signals:
    ...     c.update(d)
    ... 
    >>> c
    Counter({'signal_4': 27, 'signal_7': 24, 'signal_1': 21, 'signal_3': 18, 'signal_10': 15, 'signal_2': 15, 'signal_9': 12, 'signal_6': 9, 'signal_5': 6, 'signal_8': 3})
    

    For Op's sake, can you briefly describe what's happening here?

    A Counter works similar to a dict, but its update method adds values to the values of pre-existing keys instead of overriding them.

    0 讨论(0)
  • 2020-12-20 22:07

    Your current code uses one accumulating sum for all the signals, when instead you need a seperate the sum for each signal.

    If you want your original code to work, you need to first check if the key exists in result, and initialise it 0 beforehand if it isn't. Then accumulate the sum for the respective key.

    Code:

    result = {}
    for elm in original_list:
        for k, v in elm.items():
    
            # Initialise it if it doesn't exist
            if k not in result:
                result[k] = 0
    
            # accumulate sum seperately 
            result[k] += v
    
    print(result)
    

    Output:

    {'signal_9': 12, 'signal_8': 3, 'signal_1': 21, 'signal_3': 18, 'signal_2': 15, 'signal_5': 6, 'signal_4': 27, 'signal_7': 24, 'signal_6': 9, 'signal_10': 15}
    

    Note: As others have shown, to avoid initialising yourself, you can use collections.defaultdict() or collections.Counter() instead.

    0 讨论(0)
  • 2020-12-20 22:15

    The problem with your code is that you are summing sm and v no matter the key. Below you can find a reformatted version of your code that works. It simply adds the values from each element from the list to the result object:

    from collections import defaultdict
    
    result = defaultdict(int)
    
    for elm in original_list:
        for k, v in elm.items():
            result[k] += v
    print(result)
    

    Or, with a one liner you can have:

    result = {key: sum(e[key] for e in original_list) for key in original_list[0].keys()}
    
    0 讨论(0)
  • 2020-12-20 22:23

    What you want is the Counter collection type. The Python docs on collections describe it best, but essentially a Counter is a special kind of dictionary where all the values are integers. You can pass any key, including nonexistent ones, and add to them. For example:

    from collections import Counter
    
    original_list = [
        {'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8}, 
        {'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},
        {'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},
    ]
    
    result = Counter()
    
    for elem in original_list:
        for key, value in elem.items():
            result[key] += value
    
    print(result)
    

    Edit: @timgeb provides a variation on this answer which makes native use of the update() method on Counter objects. I would recommend that as the best answer here

    0 讨论(0)
  • 2020-12-20 22:24

    With itertools.groupby, you could do something like

    merged_list = sorted(p for l in original_list for p in l.items())
    groups = groupby(merged_list, key=lambda p: p[0])
    result = {signal: sum(pair[1] for pair in pairs) for signal, pairs in groups}
    

    If you can assume that each dictionary contains the exact same keys, the above can be simplified to

    {k: sum(d[k] for d in original_list) for k in original_list[0]}
    

    Note also that the data analysis library pandas makes operations such as these trivial:

    In [70]: import pandas as pd
    
    In [72]: pd.DataFrame(original_list).sum()
    Out[72]:
    signal_1     21
    signal_10    15
    signal_2     15
    signal_3     18
    signal_4     27
    signal_5      6
    signal_6      9
    signal_7     24
    signal_8      3
    signal_9     12
    dtype: int64
    
    0 讨论(0)
  • 2020-12-20 22:26

    Can you try below code

    basedict=siglist[0]
    for k in basedict.keys():
        result=[currdict[k] for currdict in siglist]
        endval=sum(result)
        print("Key %s and sum of values %d"%(k,endval))
    

    Output

    Key signal_9 and sum of values 12
    Key signal_2 and sum of values 15
    Key signal_8 and sum of values 3
    Key signal_5 and sum of values 6
    Key signal_7 and sum of values 24
    Key signal_10 and sum of values 15
    Key signal_1 and sum of values 21
    Key signal_6 and sum of values 9
    Key signal_4 and sum of values 27
    Key signal_3 and sum of values 18
    

    Note :- As we are sure that all keys in all dictionaries are same this solution works well. If you have a dictionary with non matching elements then it would result in KeyError . So be aware of that limitation

    0 讨论(0)
提交回复
热议问题