AiKw
AiKw

Reputation: 39

Get a new dictionary with the same keys using reduce function with a lambda argument

I have a list of dictionaries like this.

fruit = [{"apple": 10, "pear": 20, "banana": 30, "strawberry": 50},
{"apple": 12, "pear": 5, "banana": 20, "strawberry": 5},
{"apple": 15, "pear": 26, "banana": 32, "strawberry": 8}]

Can I write an reduce function in one line(with lambda argument) to get a new dictionary with the same keys. The value to each key of the new dictionary is the sum of all the values to the corresponding key. The expected output should be a dictionary as follows:

{'apple': 37.0, 'pear': 51.0, 'banana': 82.0, 'strawberry': 63.0}

Upvotes: 1

Views: 1062

Answers (3)

a_guest
a_guest

Reputation: 36249

The following approach uses a dict comprehension and no imports. I don't recommend to use it however:

{k: sum(f.get(k,0) for f in fruit) for k in {k for f in fruit for k in f}}
#                                           |                           |
#                                           +-- set of all fruit keys --+

Upvotes: 0

deceze
deceze

Reputation: 522042

A dict-comprehension can do the work of merging two dicts like this:

>>> from functools import reduce
>>> fruit = [{"apple": 10, "pear": 20, "banana": 30, "strawberry": 50},
...          {"apple": 12, "pear": 5, "banana": 20, "strawberry": 5},
...          {"apple": 15, "pear": 26, "banana": 32, "strawberry": 8}]
>>> reduce(lambda a, b: {k: a[k] + v for k, v in b.items()}, fruit)
{'apple': 37, 'pear': 51, 'banana': 82, 'strawberry': 63}

This does require that all dicts have the same keys, otherwise some will be dropped. The more complete version is this, which does get pretty unwieldy as a reduce-lambda though:

reduce(lambda a, b: {k: a.get(k, 0) + b.get(k, 0) for k in a.keys() | b.keys()}, fruit)

Upvotes: 2

user2390182
user2390182

Reputation: 73460

Util-heavy approach:

from operator import add
from collections import Counter
from functools import reduce

reduce(add, map(Counter, fruit))
# Counter({'banana': 82, 'strawberry': 63, 'pear': 51, 'apple': 37})

Or maybe more instructive for the beginner, writing an add for two dicts:

def add(d1, d2):
    return {k: d1.get(k, 0) + d2.get(k, 0) for k in d1.keys() | d2.keys()}

reduce(add, fruit)

Upvotes: 3

Related Questions