Home > Mobile >  How can I collect key-value pairs of dictionaries into one large dictionary in Python?
How can I collect key-value pairs of dictionaries into one large dictionary in Python?

Time:03-25

I have a dictionary in the following format:

data = {
    'Bob': {
        'age': 12,
        'weight': 150,
        'eye_color': 'blue'
    },
    'Jim': {
        'favorite_food': 'cherries',
        'sport': 'baseball',
        'hobby': 'running'
    },
    'Tom': {
        'strength': 'average',
        'endurance': 'high',
        'heart_rate': 'low'
    }
}

What is the most Pythonic way to concatenate all of the dictionaries within dict into a new dictionary so that I would end up with something like the following:

new_dict = {
    'age': 12,
    'weight': 150,
    'eye_color': 'blue',
    'favorite_food': 'cherries',
    'sport': 'baseball',
    'hobby': 'running',
    'strength': 'average',
    'endurance': 'high',
    'heart_rate': 'low'
}

CodePudding user response:

You can use functools.reduce() to build up the result, unioning one dictionary at a time:

from functools import reduce

data = {
 'Bob' : { 'age': 12, 'weight': 150, 'eye_color': 'blue' },
 'Jim' : { 'favorite_food': 'cherries', 'sport': 'baseball', 'hobby': 'running' },
 'Tom' : { 'strength': 'average', 'endurance': 'high', 'hear_rate': 'low' }
}

result = reduce(lambda x, y: dict(**x, **y), data.values(), {})

print(result)

This outputs:

{'age': 12, 'weight': 150, 'eye_color': 'blue', 'favorite_food': 'cherries',
'sport': 'baseball', 'hobby': 'running', 'strength': 'average',
'endurance': 'high', 'hear_rate': 'low'}

On Python 3.9 or higher, you can use lambda x: x | y, operator.or_, or dict.__or__ instead of lambda x: dict(**x, **y) if you're on Python 3.9 or higher. The latter two are from a suggestion by Mad Physicist.

CodePudding user response:

One option is to use a dictionary comprehension with a nested generator expression:

new_dict = {k: v for d in data.values() for k, v in d.items()}

Another way that's subtly different to to use collections.ChainMap:

new_dict = collections. ChainMap(*data.values())

In this case, new_dict will not be a dict, but will quack like one just fine. Lookup will be a bit slower, but construction will be faster.

  • Related