Python рекурсивно печатает вложенный хеш - PullRequest
0 голосов
/ 13 мая 2018

Я хотел бы напечатать вложенный хэш в Python, начиная с этого:

example_dict = {
    'key1' : 'value1',
    'key2' : {
        'key2a': 'value2a'
    },
    'key3' : {
        'key3a': {
            'key3aa': 'value3aa',
            'key3ab': 'value3ab',
            'key3ac': 'value3ac'
        },
        'key3b': [
            'value3b1',
            'value3b2'
        ]
    },
}

примерно так:

key1 value1
key2 key2a value2a
key3 key3a key3aa value3aa
key3 key3a key3ab value3ab
key3 key3a key3ac value3ac
key3 key3b value3b1
key3 key3b value3b2

Я не очень знаком с Python, и после парычасы я все еще застрял.

Я сейчас работаю над этой функцией:

def recursive(src, res, line = ''):
    if isinstance(src, dict):
        for key, value in src.items():
            line += str(' ' + key)
            recursive(value, res, line)
    elif isinstance(src, list):
        for litem in src:
            recursive(litem, res, line)
    else:
        line += str(' ' + str(src))
        res.append(line)

Я пытаюсь добавить каждую строку в список, чтобы иметь возможность использовать его позже, но яЯ думаю, что у меня нет правильного подхода к моей общей переменной (строке), потому что при каждом dict рекурсивный вызов выполняется с еще одним ключом dict того же уровня глубины, поэтому я получил следующее:

 key3 key3a key3aa value3aa
 key3 key3a key3aa key3ac value3ac
 key3 key3a key3aa key3ac key3ab value3ab
 key3 key3a key3b value3b1
 key3 key3a key3b value3b2
 key3 key2 key2a value2a
 key3 key2 key1 value1

Какой бы Pythonic способ сделать это?

Ответы [ 3 ]

0 голосов
/ 13 мая 2018

Используя генератор (yield оператор), вы можете сделать это рекурсивно, как:

Код:

def recursive(src, so_far=()):
    if isinstance(src, dict):
        for key, value in src.items():
            yield from recursive(value, so_far + (key,))
    elif isinstance(src, list):
        for item in src:
            yield from recursive(item, so_far)
    else:
        yield ' '.join(so_far + (src,))

Одна вещь, на которую следует обратить внимание, - это необходимость повторного получения результатов от генератора, который использовался повторно. Это делается здесь с помощью:

yield from recursive(item, so_far)

Что эквивалентно:

for i in recursive(item, so_far):
    yield i

Тестовый код:

example_dict = {
    'key1': 'value1',
    'key2': {
        'key2a': 'value2a'
    },
    'key3': {
        'key3a': {
            'key3aa': 'value3aa',
            'key3ab': 'value3ab',
            'key3ac': 'value3ac'
        },
        'key3b': [
            'value3b1',
            'value3b2'
        ]
    },
}

for line in recursive(example_dict):
    print(line)

Результаты:

key1 value1
key2 key2a value2a
key3 key3a key3aa value3aa
key3 key3a key3ab value3ab
key3 key3a key3ac value3ac
key3 key3b value3b1
key3 key3b value3b2
0 голосов
/ 13 мая 2018

Довольно простая рекурсивная реализация.

def pr(t, pref=''):
    for k, v in t.items():
        if isinstance(v, dict):
            pr(v, pref=(pref + k + ' '))
        elif isinstance(v, list):
            for el in v:
                if isinstance(el, str):
                    print(pref + ' ' + k + ' ' + el)
                else:
                    pr(el, pref=k + ' ')
        else:
            print(pref + ' ' + k + ' ' + v)
0 голосов
/ 13 мая 2018

Я получил это на работу, но это немного странно, использование append добавляет один элемент, а extend добавляет все элементы в списке.Надеюсь, это поможет:

def recursive(src, start=""):
    lst = []
    for k, v in src.items():
        new_start = "{} {}".format(start, k)
        if isinstance(v, dict):
            lst.extend(recursive(v, start=new_start))
        elif isinstance(v, list):
            lst.extend("{}: {}".format(new_start[1:] , val) for val in v)
        else:
            lst.append("{}: {}".format(new_start[1:] , v))

    return lst


items = recursive(example_dict)
for item in items:
    print(item)

Вывод:

 key1: value1
 key2 key2a: value2a
 key3 key3a key3aa: value3aa
 key3 key3a key3ab: value3ab
 key3 key3a key3ac: value3ac
 key3 key3b: value3b1
 key3 key3b: value3b2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...