elegant way to reduce a list of dictionaries?

前端 未结 5 1254
我在风中等你
我在风中等你 2021-01-13 02:30

I have a list of dictionaries and each dictionary contains exactly the same keys. I want to find the average value for each key and I would like to know how to do it using r

5条回答
  •  我在风中等你
    2021-01-13 03:20

    Here you go, a solution using reduce():

    from functools import reduce  # Python 3 compatibility
    
    summed = reduce(
        lambda a, b: {k: a[k] + b[k] for k in a},
        list_of_dicts,
        dict.fromkeys(list_of_dicts[0], 0.0))
    result = {k: v / len(list_of_dicts) for k, v in summed.items()}
    

    This produces a starting point with 0.0 values from the keys of the first dictionary, then sums all values (per key) into a final dictionary. The sums are then divided to produce an average.

    Demo:

    >>> from functools import reduce
    >>> list_of_dicts = [
    ...   {
    ...     "accuracy": 0.78,
    ...     "f_measure": 0.8169374016795885,
    ...     "precision": 0.8192088044235794,
    ...     "recall": 0.8172222222222223
    ...   },
    ...   {
    ...     "accuracy": 0.77,
    ...     "f_measure": 0.8159133315763016,
    ...     "precision": 0.8174754717495807,
    ...     "recall": 0.8161111111111111
    ...   },
    ...   {
    ...     "accuracy": 0.82,
    ...     "f_measure": 0.8226353934130455,
    ...     "precision": 0.8238175920455686,
    ...     "recall": 0.8227777777777778
    ...   }, # ...
    ... ]
    >>> summed = reduce(
    ...     lambda a, b: {k: a[k] + b[k] for k in a},
    ...     list_of_dicts,
    ...     dict.fromkeys(list_of_dicts[0], 0.0))
    >>> summed
    {'recall': 2.4561111111111114, 'precision': 2.4605018682187287, 'f_measure': 2.4554861266689354, 'accuracy': 2.37}
    >>> {k: v / len(list_of_dicts) for k, v in summed.items()}
    {'recall': 0.8187037037037038, 'precision': 0.820167289406243, 'f_measure': 0.8184953755563118, 'accuracy': 0.79}
    >>> from pprint import pprint
    >>> pprint(_)
    {'accuracy': 0.79,
     'f_measure': 0.8184953755563118,
     'precision': 0.820167289406243,
     'recall': 0.8187037037037038}
    

提交回复
热议问题