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 (viashowslist), otherwise separate entries in merged result convert_event: takes event it's in initial list , converts event output list:- strips out
name,categorykeys - aggregates
prices_*entries in dictionary list correspondingpriceskey
- strips out
merge_events_data: iterates on initial event list ,- if event not present in output list (no entry matching
name,categoryvalues), creates it - if such event found, content (
shows) augmented current event data
- if event not present in output list (no entry matching
- 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
Post a Comment