Как объединить и суммировать значения 2-х вложенных словарей и сохранить несуществующий ключ: пары значений - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть 2 словаря:

Dict1;

    {   'y2019': {   'M09': {   'Day 20': {   'lane_1': Decimal('833'),
                                      'lane_2': Decimal('1041'),
                                      'lane_3': Decimal('4702'),
                                      'lane_4': Decimal('5038'),
                                      'total': Decimal('11614')},
                        'lane_1': Decimal('1519'),
                        'lane_2': Decimal('1872'),
                        'lane_3': Decimal('8886'),
                        'lane_4': Decimal('9195'),
                        'total': Decimal('21472')},
             'M10': {   'Day 01': {   'lane_1': Decimal('530'),
                                      'lane_2': Decimal('632'),
                                      'lane_3': Decimal('3964'),
                                      'lane_4': Decimal('3756'),
                                      'total': Decimal('8882')},
                        'Day 12': {   'lane_1': Decimal('355'),
                                      'lane_2': Decimal('331'),
                                      'lane_3': Decimal('3062'),
                                      'lane_4': Decimal('3066'),
                                      'total': Decimal('6814')},
                        'Day 16': {   'lane_1': Decimal('551'),
                                      'lane_2': Decimal('638'),
                                      'lane_3': Decimal('3770'),
                                      'lane_4': Decimal('3738'),
                                      'total': Decimal('8697')},
                        'lane_1': Decimal('1436'),
                        'lane_2': Decimal('1601'),
                        'lane_3': Decimal('10796'),
                        'lane_4': Decimal('10560'),
                        'total': Decimal('24393')},
             'M11': {   'Day 03': {   'lane_1': Decimal('524'),
                                      'lane_2': Decimal('599'),
                                      'lane_3': Decimal('3370'),
                                      'lane_4': Decimal('3247'),
                                      'total': Decimal('7740')},
                        'lane_1': Decimal('524'),
                        'lane_2': Decimal('599'),
                        'lane_3': Decimal('3370'),
                        'lane_4': Decimal('3247'),
                        'total': Decimal('7740')},
             'lane_1': Decimal('5870'),
             'lane_2': Decimal('5992'),
             'lane_3': Decimal('36947'),
             'lane_4': Decimal('35423'),
             'total': Decimal('84232')}}

Dict2;

{   'y2019': {   'M09': {   'Day 12': {   'lane_1': 686,
                                      'lane_2': 831,
                                      'lane_3': 4184,
                                      'lane_4': 4157,
                                      'total': 9858},
                        'lane_1': 686,
                        'lane_2': 831,
                        'lane_3': 4184,
                        'lane_4': 4157,
                        'total': 9858},
             'lane_1': 686,
             'lane_2': 831,
             'lane_3': 4184,
             'lane_4': 4157,
             'total': 9858}}

Я хотел бы суммировать совпадающие ключи в dict1 и dict2, обновить общее количество соответствующего месяца и года соответственно в dict1. Если ключ dict2 отсутствует в dict1, мне нужно добавить его, а затем суммировать снова.

Таким образом, вывод должен быть;

    {   'y2019': {   'M09': {   'Day 20': {   'lane_1': Decimal('833'),
                                  'lane_2': Decimal('1041'),
                                  'lane_3': Decimal('4702'),
                                  'lane_4': Decimal('5038'),
                                  'total': Decimal('11614')},
                         'Day 12': {   'lane_1': Decimal('686'),
                                  'lane_2': Decimal('831'),
                                  'lane_3': Decimal('4184'),
                                  'lane_4': Decimal('4157'),
                                  'total': Decimal('9858')},
                    'lane_1': Decimal('1519 + ')},'),
                    'lane_2': Decimal('1872 + 831'),
                    'lane_3': Decimal('8886 + 4184'),
                    'lane_4': Decimal('9195 + 4157'),
                    'total': Decimal('21472 + 9858')},
         'M10': {   'Day 01': {   'lane_1': Decimal('530'),
                                  'lane_2': Decimal('632'),
                                  'lane_3': Decimal('3964'),
                                  'lane_4': Decimal('3756'),
                                  'total': Decimal('8882')},
                    'Day 12': {   'lane_1': Decimal('355'),
                                  'lane_2': Decimal('331'),
                                  'lane_3': Decimal('3062'),
                                  'lane_4': Decimal('3066'),
                                  'total': Decimal('6814')},
                    'Day 16': {   'lane_1': Decimal('551'),
                                  'lane_2': Decimal('638'),
                                  'lane_3': Decimal('3770'),
                                  'lane_4': Decimal('3738'),
                                  'total': Decimal('8697')},
                    'lane_1': Decimal('1436'),
                    'lane_2': Decimal('1601'),
                    'lane_3': Decimal('10796'),
                    'lane_4': Decimal('10560'),
                    'total': Decimal('24393')},
         'M11': {   'Day 03': {   'lane_1': Decimal('524'),
                                  'lane_2': Decimal('599'),
                                  'lane_3': Decimal('3370'),
                                  'lane_4': Decimal('3247'),
                                  'total': Decimal('7740')},
                    'lane_1': Decimal('524'),
                    'lane_2': Decimal('599'),
                    'lane_3': Decimal('3370'),
                    'lane_4': Decimal('3247'),
                    'total': Decimal('7740')},
         'lane_1': Decimal('5870 + 686'),
         'lane_2': Decimal('5992 + 831'),
         'lane_3': Decimal('36947 + 4184'),
         'lane_4': Decimal('35423 + 4157'),
         'total': Decimal('84232 + 9858')}}

Вот то, что я пробовал до сих пор;

def merge(d, new_d):
    for k, v in new_d.items():
        if isinstance(v, dict):
            merge(d[k], v)
        else: 
            d[k] = d.setdefault(k, 0) + v
merge(dict1, dict2)

Но я получаю KeyError: 'Day 12'

Я пытался добавить ключ с помощью оператора try и catch, но не смог получить сумму из него. Любая помощь приветствуется. :)

1 Ответ

0 голосов
/ 24 апреля 2020

Вот как я это решил;

def merge(original_dict, new_dict):
    """
        Sum values of two nested dicts
    """
    for key, value in new_dict.items():
        if isinstance(value, dict):
            try:
                merge(original_dict[key], value)
            except KeyError:
                original_dict[key] = {}
                merge(original_dict[key], value)
        else:
            original_dict[key] = original_dict.setdefault(key, 0) + value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...