Как вывести неорганизованные словари в список? - PullRequest
2 голосов
/ 07 марта 2020

Я попытался сгладить неорганизованный словарь (который, в свою очередь, был взят из файла json), чтобы облегчить извлечение информации. Ниже приведен пример структуры словаря и моя попытка его уплощения:

data = {'horse':{'speed':{"walk": 40, "run":50}}, 'dog':{'run':30}, 'human':{'gait':{'normal':{'run': 25, 'walk': 30}}}}

flat_dict = []
for items in list(data.items()):
    flat_list = []
    flat_list.append(items[0])
    try:
        for item in list(items[1].items())[0]:
            if type(item) is not dict: 
                flat_list.append(item)
            else:
                flat_list.append(list(item.keys())[0])
                flat_list.append(list(item.values())[0])
    except:
        flat_list.append(items[0])
    flat_dict.append(flat_list)

print(flat_dict)

Однако приведенный выше код не сглаживает весь словарь, и некоторая информация теряется, вот вывод приведенного выше кода:

[['horse', 'speed', 'walk', 40], ['dog', 'run', 30], ['human', 'gait', 'normal', {'run': 25, 'walk': 30}]]

То, что я хотел, было:

[['horse', 'speed', 'walk', 40, 'run', 50], ['dog', 'run', 30], ['human', 'gait', 'normal', 'run', 25, 'walk', 30]]

Что мне делать?

Ответы [ 3 ]

5 голосов
/ 07 марта 2020

вы можете использовать рекурсивный подход с пониманием списка:

 def gen(d):
    if isinstance(d, dict):
        for k, v in d.items():
            yield k
            yield from gen(v)
    else:
        yield d 

[[k, *gen(v)] for k, v in data.items()]

вывод:

 [['horse', 'speed', 'walk', 40, 'run', 50],
 ['dog', 'run', 30],
 ['human', 'gait', 'normal', 'run', 25, 'walk', 30]]
1 голос
/ 07 марта 2020

Ответили на вопрос:

data = {
    'horse': {
        'speed': {
            "walk": 40, "run": 50}},
    'dog': {
        'run': 30},
    'human': {
        'gait': {
            'normal': {
                'run': 25, 'walk': 30}}}}


def my_flatten(ddict, mylist):
    for k, v in ddict.items():
        if isinstance(v, dict):
            mylist.append(k)
            my_flatten(v, mylist)
        else:
            mylist.extend([k, v])
    return mylist


flist = [my_flatten(v, [k]) for k, v in data.items()]
print(flist)
1 голос
/ 07 марта 2020

Поскольку вы не знаете структуру внутри dict, вы не можете использовать простые циклы для обработки каждого случая, вам нужно использовать рекурсию, я бы предложил вспомогательный метод, чтобы рекурсивно сгладить любую структуру, а затем использовать ее для сделать массивы из [key, flatten(values)]

def flatten(values) -> list:
    if isinstance(values, list):
        return [v for value in values for v in flatten(value)]
    if isinstance(values, dict):
        return [*values.keys(), *flatten(list(values.values()))]
    return [values]


def flatten_dict(values: dict) -> list:
    return [[key, *flatten(value)] for key, value in values.items()]


if __name__ == '__main__':
    # ['foo']
    print(flatten('foo'))

    # ['foo', 'bar', 'uio', 1, 2, 3, 'k1', 'k2', 'v1', 'kk1', '9', 5, 9, 8, 7]
    print(flatten(['foo', ['bar', 'uio', [1, 2, 3]], {'k1': 'v1', 'k2': {'kk1': ['9', 5, 9, 8, 7, ]}}]))

    data = {'horse': {'speed': {"walk": 40, "run": 50}}, 'dog': {'run': 30},
            'human': {'gait': {'normal': {'run': 25, 'walk': 30}}}}

    # [['horse', 'speed', 'walk', 'run', 40, 50], ['dog', 'run', 30], ['human', 'gait', 'normal', 'run', 'walk', 25, 30]]
    print(flatten_dict(data))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...