@Mikkkch

Как лаконично обновить словарь, содержащийся в другом словаре?

Искал во многих местах ответ - не нашел. Писал самостоятельно - замучался.
Есть дефолтный словарь, а есть переопределенный, представим, что они выглядят вот так:
default = {
    'some_number': 5,
    'numbers': {
        '1': 1,
        '2': 2,
        '3': 3
    },
    'additional_number': 15
}

overridden = {
    'some_number': 10,
    'numbers': {
        '1': 2
    }
}

Если вызвать следующий код:
default.update(overridden)
То на выходе получится такой словарь:
overridden = {
    'some_number': 10,
    'numbers': {
        '1': 2
    }
    'additional_number': 15
}

То есть ключи, которые были изначально определены в подсловаре словаря default не были добавлены в измененную версию. Мне нужно, чтобы ключи переопределялись, и те, которые не были переопределены оставались на месте. Есть ли какой-то лаконичный способ решить эту проблему? Потому-что городить у себя что-то низкоуровневое желания нет, опускался сегодня до того, что писал метод, который собирает все переопределенные ключи, определяя, переопределены ли они, в цикле оператором != и потом искал среди этих ключей словари, но от такого ужаса голова дымит. Помогите!!!
  • Вопрос задан
  • 119 просмотров
Решения вопроса 2
@deliro
Агрессивное программирование
Т.к. ты ничего не ответил на мой вопрос про списки, стало быть, они не нужны. Тогда ответ такой:

def merge_dicts(d1, d2):
    result = d1.copy()
    
    for key, value in d2.items():
        if key in result and isinstance(value, dict) and isinstance(result[key], dict):
            result[key] = merge_dicts(result[key], value)
        else:
            result[key] = value
    return result
Ответ написан
phaggi
@phaggi Куратор тега Python
лужу, паяю, ЭВМы починяю
Я тут свой велосипедик сочинил:
велосипедик
from pprint import pprint

default = {
    'some_number': 5,
    'numbers': {
        '1': 1,
        '2': 2,
        '3': 3
    },
    'test2':
        {'test3': {'t1': 11,
                   't2': 22},
         'test4': {'tt1': 111,
                   'tt2': 222}
         },
    'additional_number': 15
}

overridden = {
    'some_number': 10,
    'numbers': {
        '1': 2
    },
    'test2':
        {'test4': {'tt1': 1111}
         },
}


def update_dict(default, overridden):
    for key in default.keys():
        if key in overridden.keys():
            if isinstance(default[key], dict):
                default[key] = update_dict(default[key], overridden[key])
            else:
                default[key] = overridden[key]
    return default


pprint(update_dict(default, overridden))
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
adugin
@adugin Куратор тега Python
def update(d1, d2):
    for key, value in d2.items():
        if isinstance(value, dict):
            d1.setdefault(key, {}).update(value)
        else:
            d1[key] = value
            
update(default, overridden)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы