Вот, пожалуйста:
from pprint import pprint
def merge_working(pre, post):
if not (isinstance(pre, dict) and isinstance(post, dict)):
return post
new = pre.copy() # values for unique keys of pre will be preserved
for key, post_value in post.items():
new[key] = merge_working(new.get(key), post_value)
return new
def merge_simplest(pre, post):
if not isinstance(pre, dict):
return post
return {key: merge_simplest(pre[key], post[key])
for key in pre}
merge = merge_working
def reduce_maps(*objects):
new = objects[0]
for post in objects[1:]:
new = merge(new, post)
return new
seed = {
'update': False,
'data': {
'subdata': {
'field1': 5,
'field2': '2018-01-30 00:00:00'
},
'field3': 2,
'field4': None
},
'data_updates': {},
'subdata_updates': {},
'diffs': {}
}
update_1 = {
'update': True,
'data': {
'subdata': {
'field1': 6,
'field2': '2018-01-30 00:00:00'
},
'field3': 2,
'field4': None
},
'data_updates': {},
'subdata_updates': {'field1': 6},
'diffs': {
'field1': {
'field': 'field 1',
'before': 5,
'after': 6
}
}
}
update_2 = {
'update': True,
'data': {
'subdata': {
'field1': 5,
'field2': '2018-01-30 00:00:00',
},
'field3': 2,
'field4': 1
},
'data_updates': {'field4': 1},
'subdata_updates': {}, # was subdata_update
'diffs': {
'field4': {
'field': 'field 4',
'before': None,
'after': 1
}
}
}
result = reduce_maps(*[seed, update_1, update_2])
golden = {
'update': True,
'data': {
'subdata': {
'field1': 5, # was 6
'field2': '2018-01-30 00:00:00',
},
'field3': 2,
'field4': 1
},
'data_updates': {'field4': 1},
'subdata_updates': {'field1': 6}, # was subdata_update
'diffs': {
'field1': {
'field': 'field 1',
'before': 5,
'after': 6
},
'field4': {
'field': 'field 4',
'before': None,
'after': 1
}
}
}
pprint(result)
pprint(golden)
assert result == golden
Я исправил опечатки в ваших данных (см. Комментарии в коде).
Обратите внимание, что merge
может потребоваться настройка в соответствии с точными правилами слияния и возможными данными. Чтобы понять, что я имею в виду, используйте merge = merge_simplest
и поймите, почему это не удается. Не было бы, если бы «независимая от данных» форма (понимаемая как дерево словарей без учета значений листьев) была бы на самом деле одинаковой.