python - How to merge list of dicts with same key where values are the same? -


python newbe here. have looked @ stack overflow cannot find question similar this. trying merge list of dicts have same key , values same (so in case merge name same).

this current list:

current = [     {'name' : 'food festival', 'category' : ['miscellaneous', 'undefined'], 'venue' : 'venue_1', 'price_1' : 100, 'price_2' : 120, 'start' : '2017-10-04t14:30:00z'},     {'name' : 'food festival', 'category' : ['miscellaneous', 'undefined'], 'venue' : 'venue_2', 'price_1' : 150, 'price_2' : 200, 'start' : '2017-11-04t14:30:00z'},     {'name' : 'music festival', 'category': ['music', 'pop'], 'venue' : 'venue_3', 'price_1' : 300, 'price_2' : 320, 'start' : '2017-12-04t14:30:00z'}     ] 

and trying achieve:

final = [   {     'name': 'food festival',     'category': ['miscellaneous', 'undefined'],     'shows': [       {         'start': '2017-10-04t14:30:00z',         'venue': 'venue_1',         'prices': [           { 'price_1' : 100 },           { 'price_2' : 120}         ]       },       {         'start': '2017-11-04t14:30:00z',         'venue': 'venue_2',         'prices': [           { 'price_1': 150 },           { 'price_2' : 200 }         ]       }     ]   },   {     'name': 'music festival',     'category': ['music', 'pop'],     'shows': [       {         'start': '2017-12-04t14:30:00z',         'venue': 'venue_3',         'prices': [           { 'price_1' : 300 },           { 'price_2' : 320}         ]       }    ]   } ] 

here's code:

from pprint import pprint pp   current = [     {'name' : 'food festival', 'category' : ['miscellaneous', 'undefined'], 'venue' : 'venue_1', 'price_1' : 100, 'price_2' : 120, 'start' : '2017-10-04t14:30:00z'},     {'name' : 'food festival', 'category' : ['miscellaneous', 'undefined'], 'venue' : 'venue_2', 'price_1' : 150, 'price_2' : 200, 'start' : '2017-11-04t14:30:00z'},     {'name' : 'music festival', 'category': ['music', 'pop'], 'venue' : 'venue_3', 'price_1' : 300, 'price_2' : 320, 'start' : '2017-12-04t14:30:00z'} ]   special_event_keys = ("name", "category") invalid_index = -1   def convert_event(event, special_event_keys=special_event_keys):     ret = dict()     prices_list = list()     key in event:         if key in special_event_keys:             continue         elif key.startswith("price_"):             prices_list.append({key: event[key]})         else:             ret[key] = event[key]     ret["prices"] = prices_list     return ret   def merge_events_data(events, special_event_keys=special_event_keys):     ret = list()     event in events:         existing_index = invalid_index         idx, obj in enumerate(ret):             key in special_event_keys:                 if obj[key] != event[key]:                     break             else:                 existing_index = idx         if existing_index == invalid_index:             new_object = dict()             key in special_event_keys:                 new_object[key] = event[key]             new_object["shows"] = [convert_event(event, special_event_keys=special_event_keys)]             ret.append(new_object)         else:             ret[existing_index]["shows"].append(convert_event(event, special_event_keys=special_event_keys))     return ret;   def main():     merged_events = merge_events_data(current)     print("\nresulting object:\n")     pp(merged_events)     #print("equal:", merged_events == final) # commented out avoid including contents of 'final' in answer large; add , decomment testing purpose   if __name__ == "__main__":     main() 

notes:

  • the algorithm relies on fact if 2 (input) events have same values keys: name , category, merged (via shows list), otherwise separate entries in merged result
  • convert_event: takes event it's in initial list , converts event output list:
    • strips out name , category keys
    • aggregates prices_* entries in dictionary list corresponding prices key
  • merge_events_data: iterates on initial event list ,
    • if event not present in output list (no entry matching name , category values), creates it
    • if such event found, content (shows) augmented current event data
  • code python3 , python2 compatible
  • it can improved both style , performance pov

output:

e:\work\dev\stackoverflow\q45794604>c:\install\x64\python\3.5.3\python.exe a.py  merged object:  [{'category': ['miscellaneous', 'undefined'],   'name': 'food festival',   'shows': [{'prices': [{'price_2': 120}, {'price_1': 100}],              'start': '2017-10-04t14:30:00z',              'venue': 'venue_1'},             {'prices': [{'price_2': 200}, {'price_1': 150}],              'start': '2017-11-04t14:30:00z',              'venue': 'venue_2'}]},  {'category': ['music', 'pop'],   'name': 'music festival',   'shows': [{'prices': [{'price_2': 320}, {'price_1': 300}],              'start': '2017-12-04t14:30:00z',              'venue': 'venue_3'}]}] 

Comments

Popular posts from this blog

python - Operations inside variables -

Generic Map Parameter java -

arrays - What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it? -