Maybe I didn't understand the problem right, but why would one need big clunky libraries for this when 33 lines of python code can do the whole thing?
import pprint
def flatten_and_merge(dict_list, key_list):
collect_dict = {}
for dict_list_entry in dict_list:
result_dict = {}
# first flatten everything into result_dict
for (key,value) in dict_list_entry.items():
if isinstance(value,list) and len(value)>0 and isinstance(value[0],dict):
for subdict in value:
for (subkey,subvalue) in subdict.items():
target = result_dict.get(subkey)
if not target:
target = []
result_dict[subkey] = target
target.append(subvalue)
elif key not in key_list:
result_dict[key] = [ value ] # make all other fields into collection-lists
else:
result_dict[key] = value # transfer key values unchanged
# finally merge the resulting dictionary into the one with the same key values
dict_key = '\u0000'.join(result_dict.get(key) for key in key_list)
target = collect_dict.get(dict_key)
if not target:
collect_dict[dict_key] = result_dict
else:
for (key,value) in result_dict.items():
if key not in key_list:
if key in target:
target.get(key).extend(value)
else:
target[key] = value
return collect_dict.values()
if __name__ == '__main__':
dict_list = [
{'key1': 'value1',
'key2': 'value2',
'some_value_to_keep': 'kept_value1',
'some_list_to_keep': [ 'list_value_1', 'list_value_2' ],
'nested_dicts': [
{'nested_key1': 'nested_value_1',
'nested_key2': 'nested_value_2',
},
{'nested_key1': 'nested_value_3',
'nested_key2': 'nested_value_4',
}]
},
{'key1': 'value1',
'key2': 'value2',
'some_value_to_keep': 'kept_value2',
'some_list_to_keep': [ 'list_value_3', 'list_value_4' ],
'some_other_list_to_keep': [ 'list_value_5', 'list_value_6' ],
'nested_dicts': [
{'nested_key1': 'nested_value_5',
'nested_key2': 'nested_value_6',
},
{'nested_key1': 'nested_value_7',
'nested_key2': 'nested_value_8',
}]
},
{'key1': 'value3',
'key2': 'value4',
'some_other_value_to_keep': 'kept_value3',
'yet_another_list_to_keep': [ 'list_value_7', 'list_value_8' ],
'nested_dicts': [
{'nested_key1': 'nested_value_9',
'nested_key2': 'nested_value_10',
},
{'nested_key1': 'nested_value_11',
'nested_key2': 'nested_value_12',
}]
}
]
print('original data:\n')
pprint.PrettyPrinter().pprint(dict_list)
print('\n\nflattened and merged data\n')
flattened = flatten_and_merge(dict_list,['key1','key2'])
pprint.PrettyPrinter().pprint(flattened)
produces the following output:
original data:
[{'key1': 'value1',
'key2': 'value2',
'nested_dicts': [{'nested_key1': 'nested_value_1',
'nested_key2': 'nested_value_2'},
{'nested_key1': 'nested_value_3',
'nested_key2': 'nested_value_4'}],
'some_list_to_keep': ['list_value_1', 'list_value_2'],
'some_value_to_keep': 'kept_value1'},
{'key1': 'value1',
'key2': 'value2',
'nested_dicts': [{'nested_key1': 'nested_value_5',
'nested_key2': 'nested_value_6'},
{'nested_key1': 'nested_value_7',
'nested_key2': 'nested_value_8'}],
'some_list_to_keep': ['list_value_3', 'list_value_4'],
'some_other_list_to_keep': ['list_value_5', 'list_value_6'],
'some_value_to_keep': 'kept_value2'},
{'key1': 'value3',
'key2': 'value4',
'nested_dicts': [{'nested_key1': 'nested_value_9',
'nested_key2': 'nested_value_10'},
{'nested_key1': 'nested_value_11',
'nested_key2': 'nested_value_12'}],
'some_other_value_to_keep': 'kept_value3',
'yet_another_list_to_keep': ['list_value_7', 'list_value_8']}]
flattened and merged data
[{'key1': 'value1',
'key2': 'value2',
'nested_key1': ['nested_value_1',
'nested_value_3',
'nested_value_5',
'nested_value_7'],
'nested_key2': ['nested_value_2',
'nested_value_4',
'nested_value_6',
'nested_value_8'],
'some_list_to_keep': [['list_value_1', 'list_value_2'],
['list_value_3', 'list_value_4']],
'some_other_list_to_keep': [['list_value_5', 'list_value_6']],
'some_value_to_keep': ['kept_value1', 'kept_value2']},
{'key1': 'value3',
'key2': 'value4',
'nested_key1': ['nested_value_9', 'nested_value_11'],
'nested_key2': ['nested_value_10', 'nested_value_12'],
'some_other_value_to_keep': ['kept_value3'],
'yet_another_list_to_keep': [['list_value_7', 'list_value_8']]}]