Search code examples
pythonlistdictionarylist-comprehensiondictionary-comprehension

Creating list of dictionaries from a dictionary using list comprehension


I have a dictionary of the format:

d = {'award1' : { 'nominees': ['name1', 'name2'],
                  'presenters': ['name3', 'name4'],
                  'winner' : 'name1'
                }
     'award2' : { 'nominees': ['name5', 'name6'],
                  'presenters': ['name7', 'name8'],
                  'winner' : 'name6'
                }
    }

And I'm trying to create a list of dictionaries that separate the values, i.e., the result should be:

my_list = [ { 'award1': ['name1','name2'], 'award2': ['name5','name6'] },
            { 'award1': ['name3','name4'], 'award2': ['name7','name8'] },
            { 'award1': 'name1', 'award2': 'name6' }
          ]

Is there a way I can do this with a one-line list comprehension?

What I have tried so far:

lst = [{key:val['nominees'], key:val['presenters'], key:val['winner']} for key, val in d.items()]

And my code using a normal "for" loop:

nominees, winner, presenters = {}, {}, {}
    for key, val in d.items():
        nominees[key] = val['nominees']
        winner[key] = val['winner']
        presenters[key] = val['presenters']
lst = [nominees, winner, presenters]

Solution

  • Here's a list comprehension + dictionary comprehension version of one-liner to achieve this:

    d = {
        'award1' : { 
            'nominees': ['name1', 'name2'],
            'presenters': ['name3', 'name4'],
            'winner' : 'name1'
         },
         'award2' : {
             'nominees': ['name5', 'name6'],
             'presenters': ['name7', 'name8'],
             'winner' : 'name6'
          }
    }
    
    # List of keys to maintain the order of elements in the desired list
    nested_keys = ['nominees', 'presenters', 'winner']
    
    # In Python 3.7+: If the insertion order of key in initial dict is same as
    #                 order of desired list, we can use this to make it more generic
    # nested_keys = list(d.values())[0].keys()
    
    new_list = [{k: d[k][key] for k in d.keys()} for key in nested_keys]
    

    where new_list will hold:

    [
        {'award1': ['name1', 'name2'], 'award2': ['name5', 'name6']}, 
        {'award1': ['name3', 'name4'], 'award2': ['name7', 'name8']}, 
        {'award1': 'name1', 'award2': 'name6'}
    ]