Python defaultdict глубоко вложенная структура данных - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть список наборов данных Excel с определенной информацией, как показано ниже:

Category    Subcategory    Name
Main Dish   Noodle         Tomato Noodle
Main Dish   Stir Fry       Chicken Rice
Main Dish   Soup           Beef Goulash
Drink       Wine           Bordeaux
Drink       Softdrink      Cola

Предположим, что приведенный выше набор данных является только одним из наборов данных, моя желаемая структура данных с использованием вложенного dict и списка:

data = {0:{'data':0, 'Category':[
                                 {'name':'Main Dish', 'Subcategory':[
                                                       {'name':'Noodle', 'key':0, 'data':['key':1, 'title':'Tomato Noodle']},
                                                       {'name':'Stir Fry', 'key':1, 'data':['key':2, 'title':'Chicken Rice']},
                                                       {'name':'Soup', 'key':2, 'data':['key':3, 'title':'Beef Goulash']}]},
                                  {'name':'Drink', 'Subcategory':[
                                                       {'name':'Wine', 'key':0, 'data':['key':1, 'title':'Bordeaux']},
                                                       {'name':'Softdrink', 'key':1, 'data':['key':2, 'title':'cola'}]}]},
        1:{'data':1, 'Category':.........#Same structure as dataset 0}}

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

Я пытался использовать defaultdict, чтобы сделать это, вот мои коды:

from collections import defaultdict
data = defaultdict(dict)
cateList = ["Main Dish", "Drink"]
n = 3 # n means the number of datasets
for i in range(n):
    data[i]['data'] = i
    data[i]['category'] = defaultdict(list) 
    for j in range(len(cateList)):
        data[i]['category'][j]['name'] = cateList[j]
        data[i]['category'][j]['subcategory'] = defaultdict(list)
data

Но я получаю следующие ошибки:

TypeError                                 Traceback (most recent call last)
<ipython-input-81-298f7ff30c6a> in <module>()
      5     data[i]['category'] = defaultdict(list)
      6     for j in range(len(cateList)):
----> 7         c
      8         data[i]['category'][j]['subcategory'] = defaultdict(list)
      9 data

TypeError: list indices must be integers or slices, not str

Это выполняется в Jupyter Notebook, и кажется, что оно не позволяет мне указывать вложенный defaultdict следующим образом: data [i] ['category'] [j] ['name']= cateList [j].Так что я не совсем уверен, как построить вышеупомянутую структуру данных ... есть ли лучший способ?

Большое спасибо за вашу помощь.

1 Ответ

0 голосов
/ 25 сентября 2018

В вашей спецификации указано, что вы хотите, чтобы 'Category' ссылался на список :

data = {0:{'data':0, 'Category':[
#                               ^ a list opening bracket

, но вместо этого ваш код превращает его в словарь:

data[i]['category'] = defaultdict(list) 

но остальная часть вашего кода снова пытается обработать объект 'category' как список, используя j в качестве индекса.Поскольку вместо этого это словарь, выражение data[i]['category'][j] создает список, а data[i]['category'][j]['name'] или data[i]['category'][j]['subcategory'] пытается проиндексировать этот список строкой.

Для построения этой структуры действительно не требуется defaultdict;вы уже знаете, что хотите построить данные, и вы строите вложенные структуры прямо там с циклами.Вы можете просто использовать обычные словари и списки:

cateList = ["Main Dish", "Drink"]
n = 3 # n means the number of datasets

data = {}
for i in range(n):
    data[i] = {
        'data': i,
        'category': []
    }
    category = data[i]['category']
    for name in cateList:
        category.append({
            'name': name,
            'subcategory': []
        })

Я не совсем уверен, почему вы строите внешний словарь с целочисленными ключами, начинающимися с 0. Вы можете просто сделать этот список тоже.

...