Как (или это возможно) использовать список для извлечения вложенного словаря в Python? - PullRequest
0 голосов
/ 19 октября 2018

У меня есть словарь, подобный этому на Python:

d = {
    "k1": "v1",
    "k2": {
        "nk1": "v2"
    },
    "k3": "v3"
}

У меня есть список, в котором хранится ключ, который я хочу извлечь, и некоторые из них являются вложенными ключами:

extract = ["k1", "nk1", "k3"]

Или я могу определить его таким образом, чтобы показать, что nk1 вложено в k2, и мне не нужно значение для "k2", так как это просто вложенный словарь:

extract = ["k1", ["k2", "nk1"], "k3"]

Isесть способ перебрать этот список extract и получить все нужные мне значения, или есть более простой способ проверить, существует ли ключ во вложенном словаре?

Идеальный вывод - это словарь:

r = {
    "k1": "v1",
    "nk1": "v2",
    "k3": "v3"
}

Ответы [ 3 ]

0 голосов
/ 19 октября 2018

Вы можете использовать functools.reduce, чтобы получить значение, указанное в заданном списке ключей:

from functools import reduce
dict((k[-1], reduce(dict.get, k, d)) if isinstance(k, list) else (k, d[k]) for k in extract)

При вводе образца это возвращает:

{'k1': 'v1', 'nk1': 'v2', 'k3': 'v3'}
0 голосов
/ 19 октября 2018

Это должно сработать:

d = {
    "k1": "v1",
    "k2": {
        "nk1": "v2"
    },
    "k3": "v3"
}
extract = ["k1", "nk1", "k3"]

def get_possibly_nested_key(k, d):
    # k = key
    # d = dict
    if isinstance(k, list) and len(k) > 1:
        return get_possibly_nested_key(k[1:], d[k[0]])
    else:
        if isinstance(k, list):
            return d[k[0]]
        return d[k]

result = [get_possibly_nested_key(e, d) for e in extract]
print(result)
0 голосов
/ 19 октября 2018

Да , мы можем использовать рекурсию здесь:

def linearize(some_dict):
    result = {}
    def lin(subdic):
        for k, v in subdic.items():
            if isinstance(v, dict):
                lin(v)
            else:
                result[k] = v
    lin(some_dict)
    return result

это приводит к:

>>> linearize(d)
{'k1': 'v1', 'nk1': 'v2', 'k3': 'v3'} 

Обратите внимание, однако, что в случае поддиректории соответствующий ключ«игнорируется», это означает, что мы «теряем информацию», чтобы восстановить исходный словарь.

Если несколько поддиктариев содержат один и тот же ключ, будет использоваться значение последнего.Таким образом, вполне возможно, что результирующий словарь содержит меньше элементов значения ключа, чем (под) словари исходного словаря.

EDIT : вы также можете сделатьизвлечение следующим образом:

def extract(some_dict, to_extract):
    result = {}
    def ext(ky):
        if isinstance(ky, str):
            ky = (ky,)
        subd = some_dict
        for k in ky:
            subd = subd[k]
        result[k] = subd
    for ky in to_extract:
        ext(ky)
    return result

тогда мы получим:

>>> extract(d, ["k1", ["k2", "nk1"], "k3"])
{'k1': 'v1', 'nk1': 'v2', 'k3': 'v3'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...