0

For example in the below list, I'd like to combine all dictionaries that share the same 'id' and 'name.'

Input:

l = [{'id':'1','name':'a','key1':'1'},
     {'id':'1','name':'a','key2':'3'},
     {'id':'1','name':'a','key3':'4'},
     {'id':'2','name':'a','key5':'1'},
     {'id':'2','name':'a','key7':'c'},
     {'id':'1','name':'b','key5':'1'}]

Desired Result:

l = [{'id':'1','name':'a','key1':'1','key2':'3','key3':'4'},
     {'id':'2','name':'a','key5':'1','key7':'c'},
     {'id':'1','name':'b','key5':'1'}]

If possible, I'd like the function to also take different number of arguments for which keys the dictionaries would have to share for them to combine. For example, if I just wanted to combine based on just the 'id' instead of the 'key' and the 'name,' the result would be different.

Peter Wood
  • 23,859
  • 5
  • 60
  • 99
Chris
  • 5,444
  • 16
  • 63
  • 119
  • possible duplicate of [python quickest way to merge dictionaries based on key match](http://stackoverflow.com/questions/7327344/python-quickest-way-to-merge-dictionaries-based-on-key-match) – Mark Reed Mar 31 '15 at 10:33

2 Answers2

0

itertools.groupby does the grouping for you. All that's left to do then is to merge the list of iterables of dictionaries (grouped by id) into a list of dictionaries:

>>> import itertools    
>>> l = [ dict(reduce(lambda a, b: a + b.items(), lst, [])) for lst in \
          [ list(grouper) for key, grouper in \
            itertools.groupby(l, lambda x: (x["id"], x["name"])) ] \
        ]
>>> l
[{'id': '1', 'key1': '1', 'key2': '3', 'key3': '4', 'name': 'a'},
 {'id': '2', 'key5': '1', 'key7': 'c', 'name': 'a'},
 {'id': '1', 'key5': '1', 'name': 'b'}]

That's clearly not the most readable version to do it; you should probably use a helper function that merges the dictionaries instead of the nested list comprehensions.

Phillip
  • 13,448
  • 29
  • 41
0

Traditional Way :D

result = []

for item in l :
    check = False
    # check item, is it exist in result yet (r_item)
    for r_item in result :
        if item['id'] == r_item['id'] and item['name'] == r_item['name'] :
            # if found, add all key to r_item ( previous record)
            check = True
            r_item.update( item )
    if check == False :
        # if not found, add item to result (new record)
        result.append( item )
Chetchaiyan
  • 261
  • 2
  • 11