Извлечение элементов из вложенного словаря с вложенными результатами цикла в KeyError - PullRequest
4 голосов
/ 16 апреля 2019

Мне нужно систематически обращаться к словарям, которые вложены в список в словаре на 3-м уровне, например:

responses = {'1': {'responses': [{1st dict to be retrieved}, {2nd dict to be retrieved}, ...]},
             '2': {'responses': [{1st dict to be retrieved}, {2nd dict to be retrieved}, ...]}, ...}

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

responses = {'1': df1,
             '2': df2, ...}

Чтобы добиться этого, я построил цикл for, чтобы пройти через все ключи на первом уровне.В этом цикле я использую другой цикл для извлечения каждого элемента из вложенных диктов в новый пустой список с именем responses_df:

responses_dict = {}

for key in responses.keys():
    for item in responses[key]['responses']:
        responses_dict[key].update(item)

Однако я получаю:

KeyError: '1'

Внутренний цикл работает, если я использую его индивидуально для ключа внутри dict, но это не очень помогает мне, так как данные поступают из API и должны обновляться динамически каждые несколько минут в процессе работы.

Цикл nex для преобразования результата в кадры данных будет выглядеть следующим образом:

for key in responses_dict:
     responses_df[key] = pd.DataFrame.from_dict(responses_dict[key], orient='index')

Но я так и не попробовал это, так как первая операция не удалась.

Ответы [ 4 ]

1 голос
/ 16 апреля 2019

Попробуйте это:

from collections import defaultdict      

responses_dict = defaultdict(dict) # instead of {}

Тогда ваш код будет работать.

0 голосов
/ 16 апреля 2019

Я предпочитаю использовать словари при обновлении словаря.

Если вы обновите существующий ключ, значение этого ключа будет обновлено. Если вы обновите новую пару ключ-значение, эта пара будет добавлена ​​в этот словарь.

>>>d1 = {1: 10, 2:20}
>>>d1.update({1:20})
>>>d1
>>>{1: 20, 2:20}

>>>d1.update({3:30})
>>>d1
>>>{1: 20, 2:20, 3:30}

Попробуйте исправить вашу строку с помощью:

responses_dict = {}
for key in responses.keys():
    for item in responses[key]['responses']:
        responses_dict.update({key: item})

Так что, в основном, используйте словарь для обновления словаря, более удобочитаемого и простого.

0 голосов
/ 16 апреля 2019

Попробуйте это:

responses = {'1': {'responses': [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}]},
             '2': {'responses': [{'e': 5}, {'f': 6}]}}

result = {k: pd.DataFrame(chain.from_iterable(v['responses'])) for k, v in responses.items()}

for df in result.values():
    print(df, end='\n\n')

Выход:

   0
0  a
1  b
2  c
3  d

   0
0  e
1  f
0 голосов
/ 16 апреля 2019

На самом деле responses_dict[key], где key=1 не существует.

Таким образом, когда вы просто делаете print(responses_dict[key]), вы получаете ту же ошибку, 1 не является ключом к этому dict и update не используется, как должно быть.

Попробуйте следующий синтаксис:

responses_dict = {}

for key in responses.keys():
    print(key)
    for item in responses[key]['responses']:
        responses_dict.update(key = item)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...