Рекурсивная глубина словаря питона - PullRequest
8 голосов
/ 02 марта 2012

G'day,

Я пытаюсь найти рекурсивную глубину функции, которая перебирает словарь, и я немного растерялся ... В настоящее время у меня есть что-то вроде:

myDict = {'leve1_key1': {'level2_key1': {'level3_key1': {'level4_key_1': {'level5_key1':   'level5_value1'}}}}}

И я хочу знать, насколько вложен самый вложенный словарь ... поэтому я делаю следующее ...

def dict_depth(d, depth):

    for i in d.keys():
        if type(d[i]) is dict:
            newDict = d[i]
            dict_depth(newDict, depth+1)
    return depth

print dict_depth(myDict, 0)

Единственная проблема в том, что рекурсивный цикл возвращает только окончательное значение (0). если я положу в печать заявление for i in d.keys(): тогда я могу, по крайней мере, напечатать самое высокое значение рекурсии, но возвращение значения - это другое дело ...

Я уверен, что это просто - у меня только что есть медуза.

Приветствия

Ответы [ 5 ]

10 голосов
/ 02 марта 2012

Обязательно присвойте результат рекурсивного вызова глубина . Также, как говорит @amit, рассмотрите возможность использования max , чтобы вы могли обрабатывать дикты с несколькими парами ключ-значение (древовидная структура).

def dict_depth(d, depth=0):
    if not isinstance(d, dict) or not d:
        return depth
    return max(dict_depth(v, depth+1) for k, v in d.iteritems())

>>> myDict = {'leve1_key1': {'level2_key1': 
               {'level3_key1': {'level4_key_1': 
                  {'level5_key1':   'level5_value1'}}}}}
>>> dict_depth(myDict)
5
2 голосов
/ 07 января 2015
MyDict = {'a': {'a1': {'a11': 5, 'a12':[{2:'a22'}], 'a13':{'a14':'a11'}}, 'a2': 6}, 'b':{7:{8:{9:{10:{11:'11'}}}}}, 'c': {'c1': 18, 'c2': 1}}

def find_depth(dep,val):
    if isinstance(val,dict):
        dep=dep+1
        for j in val:
            find_depth(dep,val[j])
        temp_depth.append(dep)
        dep=0
        return max(temp_depth)
    elif isinstance(val,list):
        for k in val:
            find_depth(dep,k)


max_depth={}
for i in MyDict:
    dep=0
    temp_depth=[]
    max_depth.update({i:(find_depth(dep,MyDict[i]))})
    print max_depth

Здесь код работает нормально, если даже список также включен.

2 голосов
/ 02 марта 2012

Вы должны сохранить значение, восстановленное из рекурсивного вызова, и вернуть найденное максимальное значение, в противном случае - вы вызываете рекурсивную функцию, ничего не делая с возвращенным значением! [и возвращает 0, как и ожидалось, поскольку он никогда не менялся]

def dict_depth(d, depth):
    ret = depth 
    for i in d.keys():
        if type(d[i]) is dict:
            newDict = d[i]
            ret = max(dict_depth(newDict, depth+1),ret) #finding max and storing it
    return ret #returning the max found
0 голосов
/ 06 мая 2014

Нерекурсивная версия:

def depth(d):

    depth=0
    q = [(i, depth+1) for i in d.values() if isinstance(i, dict)]
    max_depth = 0
    while (q):
        print q
        n, depth = q.pop()
        max_depth = max(max_depth, depth)
        q = q + [(i, depth+1) for i in n.values() if isinstance(i, dict)]

    print max_depth
0 голосов
/ 02 марта 2012

Я не могу победить Рэймонда Хеттингера, если он THE R.H. ;-) Но я пришел к аналогичному решению с некоторыми заявлениями для печати, чтобы проиллюстрировать, что происходит!

d = {1: 2, 2: {3: {5: 6}}, 3: {4: 4}, 7: 8}
def recursion_depth(dict_, depth):
    for k in dict_:
        print "key{0}:value{1} = depth:{2}".format(k, dict_[k], depth)
    if type(dict_[k]) == dict:
        actual_depth = recursion_depth(dict_[k], depth+1)
        if actual_depth > depth: depth += 1
    return depth

>>>recursion_depth(d,0)
key1:value2 = depth:0
key2:value{3: {5: 6}} = depth:0
key3:value{5: 6} = depth:1
key5:value6 = depth:2
key3:value{4: 4} = depth:1
key4:value4 = depth:2
key7:value8 = depth:2
2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...