Слияние вложенных словарей Python с объединяемыми ключами на разных уровнях - PullRequest
0 голосов
/ 14 сентября 2018

Я какое-то время искал решение этой проблемы, но все решения предполагают, что присоединяемые ключи находятся на одном и том же уровне вложенности словарей.

Чтобы сделать его коротким, имея эти два слова:

dict1 = {'Head': 
            {'Face': 
                {'Eyes': 
                    {'Eyebrows': {}, 
                     'Eyelids': 
                        {'Eyelashes': {}
                        }
                    }, 
                 'Nose': {}, 
                 'Mouth': {}
                }
            }
        }
dict2 = {'Eyes': 
            {'Eyebrows': {}, 
             'Eyelids': 
                {'Eyelashes': {}
                }
            }
        }

Я хочу следующее:

dict3 = {'Head': 
            {'Face': 
                {'Eyes': 
                    {'Eyebrows': {}, 
                     'Eyelids': 
                        {'Eyelashes': {}
                        }
                    },         
                 'Nose': {}, 
                 'Mouth': {}
                }
            }
        }

Как видите, ключ "Глаза" должен быть точкой слияния в этом небольшом примере, и он находится на третьем уровнедерево в dict1 и на первом уровне в dict2.Словари могут иметь перекрытие для всех ключей / значений (на разных уровнях, как в случае с «глазами») или вообще не перекрываться, но я также должен избегать дублирования.

Дело в том,Я обнаружу, что либо один словарь уже включен в другой, либо они вообще не будут перекрываться.Я пытаюсь "обрезать" гигантское дерево, сохраняя только определенные узлы на основе поиска по слову (поиск по чистой строке).Проблема состоит в том, что некоторые из узлов (и производные, более глубокие узлы) могут включать в себя некоторые другие, но иногда они могут вообще не совпадать.Думайте об этом как о древовидном / вложенном словаре вашего тела.Вы можете искать «клетку», найти большой узел, называемый «клетками крови», который включает в себя другие узлы, такие как «клетки свертывания», «транспортные клетки» или «защитные клетки».Кроме того, в другой ветви главного дерева вы можете найти, например, «костные клетки».Все они будут найдены при поиске, некоторые из них могут включать другие («коагуляция», «транспорт» или «защитный» будет внутри «клеток крови»), но некоторые другие могут быть отделены от этого дерева («костные клетки»).).Я хочу, чтобы они были в одном глобальном вложенном дереве.

Как в этом случае объединить несколько словарей?Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Вы можете использовать простую рекурсивную функцию для обновления ваших словарей (узел: я добавил пары ключ-значение в пустые словари во входных данных, чтобы отразить фактические изменения, вносимые кодом ниже):

d = {'Head': {'Face': {'Eyes': {'Eyebrows': {}, 'Eyelids': {'Eyelashes': {}}}, 'Nose': {}, 'Mouth': {}}}}
dict2 = {'Eyes': 
           {'Eyebrows': {"color":'brown'}, 
             'Eyelids': 
            {'Eyelashes': {"type":"long", "color":"black"}
            }
        }
 }
def update_dict(d, update_with):
   if not any(i in update_with for i in d):
     return {a:update_dict(b, update_with) if isinstance(b, dict) else b for a, b in d.items()}
   return {a:update_dict(b, update_with if a not in update_with else update_with[a]) if isinstance(b, dict) and b \
       else update_with.get(a, b) for a, b in d.items()}

import json
print(json.dumps(update_dict(d, dict2), indent=4))

Выход:

{
"Head": {
    "Face": {
        "Eyes": {
            "Eyebrows": {
                "color": "brown"
            },
            "Eyelids": {
                "Eyelashes": {
                    "type": "long",
                    "color": "black"
                }
             }
         },
         "Nose": {},
         "Mouth": {}
     }
  }
}
0 голосов
/ 14 сентября 2018

Если вы не знаете, на каком уровне они пересекаются, вам нужно будет сделать что-то вроде дерева поиска в глубину, чтобы убедиться, что словарь 2 отсутствует в словаре 1, а затем добавить их оба на верхнем уровне.

Найдите уровень, а затем выполните слияние со словарем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...