Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Flatten the list of dictionaries

List of dictionaries:

data = [{          'a':{'l':'Apple',                 'b':'Milk',                 'd':'Meatball'},          'b':{'favourite':'coke',               'dislike':'juice'}          },          {          'a':{'l':'Apple1',                 'b':'Milk1',                 'd':'Meatball2'},          'b':{'favourite':'coke2',               'dislike':'juice3'}          }, ... ] 

I need to join all nested dictionaries to reach at the expected output:

 [{'d': 'Meatball', 'b': 'Milk', 'l': 'Apple', 'dislike': 'juice', 'favourite': 'coke'},   {'d': 'Meatball2', 'b': 'Milk1', 'l': 'Apple1', 'dislike': 'juice3', 'favourite': 'coke2'}] 

I try nested list comprehension, but cannot join dict together:

L = [y for x in data for y in x.values()] print (L)  [{'d': 'Meatball', 'b': 'Milk', 'l': 'Apple'},   {'dislike': 'juice', 'favourite': 'coke'},  {'d': 'Meatball2', 'b': 'Milk1', 'l': 'Apple1'},   {'dislike': 'juice3', 'favourite': 'coke2'}] 

I am looking for the fastest solution.

like image 713
jezrael Avatar asked Feb 09 '18 07:02

jezrael


People also ask

How do you flatten a dictionary with nested lists and dictionaries in Python?

Basically the same way you would flatten a nested list, you just have to do the extra work for iterating the dict by key/value, creating new keys for your new dictionary and creating the dictionary at final step. For Python >= 3.3, change the import to from collections.

How do you flatten a dictionary value in Python?

Use list comprehension to generate a non-unique list, convert it to a set to get the unique values, and then back into a sorted list. Perhaps not the most efficient, but yet another one line solution (this time with no imports). This should be the most elegant solution leveraging list/dictionary comprehension.


1 Answers

You can do the following, using itertools.chain:

>>> from itertools import chain # timeit: ~3.40 >>> [dict(chain(*map(dict.items, d.values()))) for d in data] [{'l': 'Apple',    'b': 'Milk',    'd': 'Meatball',    'favourite': 'coke',    'dislike': 'juice'},   {'l': 'Apple1',    'b': 'Milk1',    'dislike': 'juice3',    'favourite': 'coke2',    'd': 'Meatball2'}] 

The usage of chain, map, * make this expression a shorthand for the following doubly nested comprehension which actually performs better on my system (Python 3.5.2) and isn't that much longer:

# timeit: ~2.04 [{k: v for x in d.values() for k, v in x.items()} for d in data] # Or, not using items, but lookup by key # timeit: ~1.67 [{k: x[k] for x in d.values() for k in x} for d in data] 

Note:

RoadRunner's loop-and-update approach outperforms both these one-liners at timeit: ~1.37

like image 109
user2390182 Avatar answered Sep 29 '22 11:09

user2390182