Понимание словаря Python3 с под-словарем upacking? - PullRequest
0 голосов
/ 06 сентября 2018

Предположим, что у каждого есть словарь, root, который состоит из пар ключ: значение, где некоторые значения сами являются словарями.

Можно ли (и если да, то как) распаковать эти словари с помощью словарного понимания?

, например

{k: v if type(v) is not dict else **v for k, v in root.items()}

пример:

root = {'a': 1, 'b': {'c': 2, 'd': 3}}


result = {'a': 1, 'c': 2, 'd': 3}

Ответы [ 3 ]

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

Если у вас есть несколько уровней вложенных словарей, я предлагаю вам следующее решение на основе рекурсивной функции:

def flatten(res, root):
    for k,v in root.items():
        if isinstance(v, dict):
            flatten(res, v)
        else:
            res[k] = v

root = {'a': 1, 'b': {'c': 2, 'd': {'e': 5, 'f': 6}}}

result = {}
flatten(result, root)

print(result)  # {'a': 1, 'c': 2, 'e': 5, 'f': 6}
0 голосов
/ 06 сентября 2018

Вот рекурсивное решение. В функции _flatten_into_kv_pairs мы выполняем итерацию по паре ключ и значения и получаем эти ключи / значения, если значение не является словарем. Если это так, то мы рекурсивно вызываем _flatten_into_kv_pairs с помощью конструкции yield from. Функция flatten_dict - это просто оболочка, которая превращает последовательность пар ключ / значение обратно в словарь.

def _flatten_into_kv_pairs(dict_object):
    for k, v in dict_object.items():
        if isinstance(v, dict):
            yield from _flatten_into_kv_pairs(v)
        else:
            yield k, v


def flatten_dict(dict_object):
    return dict(_flatten_into_kv_pairs(dict_object))


root = {'a': 1, 'b': {'c': 2, 'd': 3, 'e': {'f': 4, 'g': 5}}}
print(flatten_dict(root))

Выход:

{'a': 1, 'c': 2, 'd': 3, 'f': 4, 'g': 5}
0 голосов
/ 06 сентября 2018

Полагаю, мне следует опубликовать ответ с более широким объяснением, чтобы помочь вам, поскольку оно немного отличается от других существующих вопросов

{
    _k: _v
    for k, v in root.items()
    for _k, _v in (         # here I create a dummy dictionary if non exists
                      v if isinstance(v, dict) else {k: v}
                  ).items() # and iterate that
}

Ключевая часть понимания заключается в том, что вам нужна последовательная и общая логика для понимания.

Вы можете сделать это, создав пустышку вложенных словарей, в которых они ранее не существовали, используя v if isinstance(v, dict) else {k: v}

Тогда это простое вложенное упражнение по распаковке словаря.

Чтобы помочь вам в дальнейшем понимании, я бы порекомендовал написать код, например,

res = dict()
for k,v in root.items():
    d = v if isinstance(v, dict) else {k: v}
    for _k, _v in d.items():
        res[_k] = _v

и работать в обратном направлении от этого

Полезные ссылки

...