Could use a for loop and keep track of the last key that was merged.
from pprint import pprint
data = [
{"SNAPSHOT": {"SnapshotVersion": "304"}},
{"SNAPSHOT": {"SnapshotCreationDate": "2015-06-21 17:33:41"}},
{"CafeData": {"CafeVersion": "2807"}},
{"CafeData": {"IsSoftwareOnly": "1"}},
{"CafeData": {"IsPassportTCPIP": "1"}},
{"SNAPSHOT": {"SnapshotVersion": "777"}},
{"SNAPSHOT": {"SnapshotCreationDate": "2017-07-27 17:37:47"}},
]
last_key = None
grouped = []
for value in data:
# Easy way to get the key of a dict with one key
curr_key = next(iter(value))
# Decide if we should work on the next entry
if last_key is None or curr_key != last_key:
grouped.append(value)
else:
# update the last value in the group with the new data
grouped[-1][curr_key].update(value[curr_key])
# Move to the next item
last_key = curr_key
pprint(grouped)
[{'SNAPSHOT': {'SnapshotCreationDate': '2015-06-21 17:33:41',
'SnapshotVersion': '304'}},
{'CafeData': {'CafeVersion': '2807',
'IsPassportTCPIP': '1',
'IsSoftwareOnly': '1'}},
{'SNAPSHOT': {'SnapshotCreationDate': '2017-07-27 17:37:47',
'SnapshotVersion': '777'}}]
Option 2 is similar, but for grouped I would just use a dict. In this case you don't need to know about the last key.
Also you need to make some assumptions on how to merge vales if there are key collisions in the nested dict.
grouped = {}
for value in data:
curr_key = next(iter(value))
curr_value = value[curr_key]
group = grouped.setdefault(curr_key, {})
for sub_key, sub_value in curr_value.items():
# check if you need to merge
if sub_key in group:
# If the key is already present, but is not a list, make it one
if not isinstance(group[sub_key], list):
group[sub_key] = [group[sub_key]]
# Add the new value to the list
group[sub_key].append(sub_value)
else:
# Otherwise just copy it over
group[sub_key] = sub_value
pprint(grouped)
{'CafeData': {'CafeVersion': '2807',
'IsPassportTCPIP': '1',
'IsSoftwareOnly': '1'},
'SNAPSHOT': {'SnapshotCreationDate': ['2015-06-21 17:33:41',
'2017-07-27 17:37:47'],
'SnapshotVersion': ['304', '777']}}