Задача
Учитывая, что диктат с несколькими уровнями сглаживает диктат на основе указанного пути ключа.
Образец входных данных
input_data = [
{
"CreatedBy": {"Name":"User001"},
"Lookup": {
"TextField": "Some text",
"UserField": {"Id": "ID001", "Name": "Name001"},
"CreatedBy": {"Name": "User001"},
},
"Image": {"a": "b"},
}
]
Тестовые случаи
Контрольный пример 1
Сглаживается, только если указанный путь соответствует
output = flatten_dict(input_data, use_keys=["Image", "Lookup.CreatedBy", "CreatedBy"])
expected = [{
'CreatedBy.Name':'User001'},
"Lookup": {
"TextField": "Some text",
"UserField": {"Id": "ID001", "Name": "Name001"},
"CreatedBy.Name": "User001",
},
"Image.a": "b",
}]
Контрольный пример 2
output = flatten_dict(input_data, use_keys=["Image", "Lookup.CreatedBy"])
expected = [{
"CreatedBy": {"Name":"User001"},
"Lookup": {
"TextField": "Some text",
"UserField": {"Id": "ID001", "Name": "Name001"},
"CreatedBy.Name": "User001",
},
"Image.a": "b",
}]
Контрольный пример 3: ключ верхнего уровня имеет приоритет Свести все дочерние пути для данного родительского пути.то есть, учитывая только «Lookup», решение сглаживается до CreatedBy.Name без явного упоминания об этом.
output = flatten_dict(input_data, use_keys=["Image", "Lookup.CreatedBy", "Lookup"])
expected = [{
"CreatedBy": {"Name":"User001"}
"Lookup.TextField": "Some text",
"Lookup.UserField.Id": "ID001",
"Lookup.UserField.Name": "Name001",
"Lookup.CreatedBy.Name": "User001",
"Image.a": "b",
}]
Вот что я пытался
Пока я ограничиваю решение доSingle Dict, позже я хочу расширить его до списка DICT.
def flatten(data, prev_key="", level=0, use_keys=["Image", "CreatedBy"]):
if isinstance(data, list):
data = data[0]
res = {}
for k, v in data.items():
if level == 0:
newkey = k
else:
newkey = prev_key + "." + k
if isinstance(v, dict):
flattened_val = flatten(data=v, prev_key=newkey, level=level + 1)
if newkey in use_keys:
res.update(flattened_val)
else:
res.update({".".join(newkey.split(".")[level-2:]): flattened_val})
else:
if newkey.split(".")[-2] in use_keys:
res.update({".".join(newkey.split(".")[level-1:]): v})
else:
res.update({k: v})
return res