#python #dictionary #recursion #key
Вопрос:
Вот уже несколько дней я ищу решение своей проблемы. Я не буду описывать все то, что я пробовал до сих пор, и просто объясню свою проблему.
Вот мои два входа:
unused_field_list = ['a.b', 'b.d.y', 'c.g', 'z']
my_dictionnary =
{
"a": {
"b": {
"key": "value"
},
"c": {
"f": {
"key": "value"
}
}
},
"b": {
"d": {
"y": {
"key": "value"
}
},
"g": {
"key": "value"
}
},
"c": {
"g" : {
"key": "value"
}
},
"z": {
"key": "value"
}
}
Вот результат, который я хотел бы получить:
{
"a": {
"c": {
"f": {
"key": "value"
}
}
},
"b": {
"g": {
"key": "value"
}
}
}
Поэтому я пытаюсь добиться того, чтобы удалить «ключи», которые у меня есть в моем unused_field_list
словаре, из моего словаря. Это не обязательно, но еще одной хорошей вещью было бы также полностью удалить ключ, если он не содержит ключей более низкого уровня (как в случае b.d
с c
ключами и в моем примере. Глубина диктанта заранее не известна и варьируется.
Я думаю, что это невозможно сделать с помощью простого подхода, но я действительно надеюсь, что есть способ сделать это довольно просто.
Ответ №1:
Вы можете использовать рекурсию:
paths = ['a.b', 'b.d.y', 'c.g', 'z']
d = {'a': {'b': {'key': None}, 'c': {'f': {'key': None}}}, 'b': {'d': {'y': {'key': 'value'}}, 'g': {'key': 'value'}}, 'c': {'g': {'key': 'value'}}, 'z': {'key': 'value'}}
def rm_d(d, p = []):
if not isinstance(d, dict):
return d
r = {a:rm_d(b, p [a]) for a, b in d.items() if '.'.join(p [a]) not in paths}
return {a:b for a, b in r.items() if not isinstance(b, dict) or b}
print(rm_d(d))
Выход:
{'a': {'c': {'f': {'key': None}}}, 'b': {'g': {'key': 'value'}}}
Ответ №2:
unused_field_list = ['a.b', 'b.d.y', 'c.g', 'z']
my_dictionnary = {
"a": {
"b": {
"key": "value"
},
"c": {
"f": {
"key": "value"
}
}
},
"b": {
"d": {
"y": {
"key": "value"
}
},
"g": {
"key": "value"
}
},
"c": {
"g" : {
"key": "value"
}
},
"z": {
"key": "value"
}
}
def filter_dict(node, filter=None, path=None):
if type(node) != dict:
return node
res = {}
if filter is None:
filter = []
if path is None:
path = ""
for k, v in node.items():
subpath = f"{path}.{k}" if path != "" else k
if subpath not in filter:
subnode = filter_dict(v, filter, subpath)
if subnode != {}:
res [k] = subnode
return res
res = filter_dict(my_dictionnary, unused_field_list)
print(res)