Home > front end >  Python quickest way to combine 2 list of dictionaries into one list of dictionary
Python quickest way to combine 2 list of dictionaries into one list of dictionary

Time:03-23

ldict1 = [{"id":1, "name":"apple", "colour": "", "type": ""}, 
          {"id":2, "name":"orange", "colour": "", "type":""}]
ldict2 = [{"id":1, "colour":"red", "type":"fruit"}, 
          {"id":2, "colour":"orange", "type":"fruit"}]

Above is an example of the 2 types of list of dictionaries I want to merge. The id is the same for both. The length of both is long. I could only think of nested for loops but that could take time. What could be the quickest way to merge the same.

Expected

ldict = [{"id":1, "name":"apple", "colour": "red", "type": "fruit"}, 
         {"id":2, "name":"orange", "colour": "orange", "type":"fruit"}]

Note that the two lists always have the same order of id. Also, I want to add the missing details of ldict1 from ldict2. Those keys are always empty in ldict1 which need to be filled by ldict2.

CodePudding user response:

You could try with:

out = [{**i, **j} for i,j in zip(ldict1, ldict2)]

or if you have Python>=3.9:

out = [i | j for i,j in zip(ldict1, ldict2)]

Output:

[{'id': 1, 'name': 'apple', 'colour': 'red', 'type': 'fruit'},
 {'id': 2, 'name': 'orange', 'colour': 'orange', 'type': 'fruit'}]

Note that this works only if the ids match each pair of i-j. Also in the event that a key has values in both i and j, only the value from j is kept.

Also, (probably wouldn't be that different from a double loop but) if the ids don't match, we could use pandas module and use it's fillna method:

import pandas as pd
out = pd.DataFrame(ldict1).replace('', float('nan')).fillna(pd.DataFrame(ldict2)).to_dict('records')

CodePudding user response:

While the other answer meets the OP's need, here's one way to merge two dicts if we don't know which dict has to be updated:

# test data
ldict1 = [{"id":1, "name":"apple", "colour": "", "type": "fruit"}, 
          {"id":2, "name":"orange", "colour": "", "type":""}]
ldict2 = [{"id":1, "colour":"red", "type":""},  # type is missing here
          {"id":2, "colour":"orange", "type":"fruit"}]

[{k: i.get(k) or j.get(k) for k in {*i, *j}} for i, j in zip(ldict1, ldict2)]       

Output:

[{'type': 'fruit', 'colour': 'red', 'id': 1, 'name': 'apple'},
 {'type': 'fruit', 'colour': 'orange', 'id': 2, 'name': 'orange'}]
  • Related