Использование Python для извлечения пар ключ / значение, вложенных на произвольных уровнях

#python #json #list

#python #json #Список

Вопрос:

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

Ответ

 [{
    "Mainframe": {
        "Production": [{
            "Host": "Alfa",
            "Response": "11ms"
        }, {
            "Host": "Beta",
            "Response": "10ms"
        }],
        "Development": [{
            "Host": "Amdar",
            "Response": "10ms"
        }]
    },
    "NT": {
        "Production": [{
            "Host": "IceOut",
            "Response": "10ms"
        }, {
            "Host": "IceInt",
            "Response": "10ms"
        }],
        "Development": [{
            "Host": "IceStage",
            "Response": "10ms"
        }, {
            "Host": "IceTest",
            "Response": "10ms"
        }]
    },
    "XML": [{
        "Host": "XMLDm",
        "Response": "10ms"
    }, {
        "Host": "XMLAm",
        "Response": "10ms"
    }]
}]
  

Новая полезная нагрузка

 "rows":[
    {
        "Host Type": "Mainframe",
        "Environment": "Production",
        "Host Name": "Alfa",
        "Response": "11 ms"
    },
    {
        "Host Type": "Mainframe",
        "Environment": "Production",
        "Host Name": "Beta",
        "Response": "10 ms"
    }
]
  

и т.д…

Комментарии:

1. Что вы пробовали, и в чем именно проблема с этим?

2. и опубликовать ожидаемый результат

Ответ №1:

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

 import pprint

response = [{
    "Mainframe": {
        "Production": [{
            "Host": "Alfa",
            "Response": "11ms"
        }, {
            "Host": "Beta",
            "Response": "10ms"
        }],
        "Development": [{
            "Host": "Amdar",
            "Response": "10ms"
        }]
    },
    "NT": {
        "Production": [{
            "Host": "IceOut",
            "Response": "10ms"
        }, {
            "Host": "IceInt",
            "Response": "10ms"
        }],
        "Development": [{
            "Host": "IceStage",
            "Response": "10ms"
        }, {
            "Host": "IceTest",
            "Response": "10ms"
        }]
    },
    "XML": [{
        "Host": "XMLDm",
        "Response": "10ms"
    }, {
        "Host": "XMLAm",
        "Response": "10ms"
    }]
}]


payload = {
    "rows": []
}


## do first pass ##

for item in response:
    for host_type, host_type_details in item.items():
        if type(host_type_details) == list:
            item[host_type] = {"Production": host_type_details}

## now read the data ##
for item in response:
    for host_type, host_type_details in item.items():
        for environment, environment_details in host_type_details.items():
            for host_details in environment_details:
                host_name = host_details["Host"]
                response_time = host_details["Response"]

                obj = {
                    "Host Type": host_type,
                    "Environment": environment,
                    "Host Name": host_name,
                    "Response": response_time
                }

                payload['rows'].append(obj)

## now print payload ##
pprint.pprint(payload)
  

Выходной сигнал:

 {'rows': [{'Environment': 'Production',
           'Host Name': 'Alfa',
           'Host Type': 'Mainframe',
           'Response': '11ms'},
          {'Environment': 'Production',
           'Host Name': 'Beta',
           'Host Type': 'Mainframe',
           'Response': '10ms'},
          {'Environment': 'Development',
           'Host Name': 'Amdar',
           'Host Type': 'Mainframe',
           'Response': '10ms'},
          {'Environment': 'Production',
           'Host Name': 'IceOut',
           'Host Type': 'NT',
           'Response': '10ms'},
          {'Environment': 'Production',
           'Host Name': 'IceInt',
           'Host Type': 'NT',
           'Response': '10ms'},
          {'Environment': 'Development',
           'Host Name': 'IceStage',
           'Host Type': 'NT',
           'Response': '10ms'},
          {'Environment': 'Development',
           'Host Name': 'IceTest',
           'Host Type': 'NT',
           'Response': '10ms'},
          {'Environment': 'Production',
           'Host Name': 'XMLDm',
           'Host Type': 'XML',
           'Response': '10ms'},
          {'Environment': 'Production',
           'Host Name': 'XMLAm',
           'Host Type': 'XML',
           'Response': '10ms'}]}
  

Чтобы решить проблему наличия списков и словарей, это делает первый проход для помещения любых данных, у которых в настоящее время нет среды, в среду — вы можете видеть, что мы превращаемся response в это:

 [{'Mainframe': {'Development': [{'Host': 'Amdar', 'Response': '10ms'}],
                'Production': [{'Host': 'Alfa', 'Response': '11ms'},
                               {'Host': 'Beta', 'Response': '10ms'}]},
  'NT': {'Development': [{'Host': 'IceStage', 'Response': '10ms'},
                         {'Host': 'IceTest', 'Response': '10ms'}],
         'Production': [{'Host': 'IceOut', 'Response': '10ms'},
                        {'Host': 'IceInt', 'Response': '10ms'}]},
  'XML': {'Production': [{'Host': 'XMLDm', 'Response': '10ms'},
                         {'Host': 'XMLAm', 'Response': '10ms'}]}}]
  

Теперь у "XML" данных явно упомянута среда, поэтому мы можем просто перебирать каждый элемент ответа, затем каждый тип хоста, затем каждую среду, а затем каждый конкретный хост, чтобы создать каждый объект данных и добавить объекты в payload["rows"] .

Комментарии:

1. Нормализация реакции в первую очередь теперь кажется очевидной. НАМНОГО проще, чем я пытался это сделать. Спасибо вам за ответ!