2014-05-06 13 views
19

zakładając mamy ten dict:poznać głębię słownika

d = {'a':1, 'b': {'c':{}}} 

co byłoby najprostszym sposobem poznania gniazdowania głębokość z tego?

+1

Może to oddział, lub tylko jeden klucz na warstwę? – mhlester

+3

czy to tylko zagnieżdżone dicts, o które się martwisz, czy też dyktują wartości, które są również innymi pojemnikami? – mgilson

+3

Będę idiotą, aby powiedzieć, że (najprostszą) odpowiedzią na przykład, który dałeś, byłoby przyjrzenie się temu. Ponadto, nie mogę uwierzyć, że to nie jest duplikat (ale wydaje się, że wyewidencjonowuje!) – keyser

Odpowiedz

28

Musisz recurse:

def depth(d, level=1): 
    if not isinstance(d, dict) or not d: 
     return level 
    return max(depth(d[k], level + 1) for k in d) 

max() jest potrzebne, aby odebrać największą głębokość obecnego słowniku pod kontrolą na każdym poziomie w , słownik z 3 kluczami każdego z różnych głębokości powinien odzwierciedlać największą głębokość na tym poziomie.

Demo:

>>> d = {'a':1, 'b': {'c':{}}} 
>>> depth(d) 
3 
>>> d = {'foo': {'bar': {'baz': 0}, 'spam': {'ham': {'monty': 1}, 'eric': 'idle'}}, 'john': 'cleese'} 
>>> depth(d) 
5 
+0

+1 jedno zastrzeżenie: powinno być None i {} return 1? Ale to kwestia konwencji. –

+1

@lukas: Technikę można zmodyfikować; chodziło raczej o to, aby pokazać, co należy zrobić. Kluczowymi punktami tutaj są rekursja i użycie 'max()', powiedziałbym. –

+0

Domyślna wartość poziomu powinna wynosić 0, a nie 1. Prosty dyktat zwraca 2 jako głębokość, która nie jest poprawna. Także dla Brak i pustych dyktatur, głębokość powinna wynosić 0, a nie 1. –

16

Musisz utworzyć rekurencyjną funkcję:

>>> def depth(d): 
...  if isinstance(d, dict): 
...   return 1 + (max(map(depth, d.values())) if d else 0) 
...  return 0 
... 
>>> d = {'a':1, 'b': {'c':{}}} 
>>> depth(d) 
3 
4

nierekursywnych rozwiązanie:

def depth(d): 

    depth=0 
    q = [(i, depth+1) for i in d.values() if isinstance(i, dict)] 
    max_depth = 0 
    while (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 
3

iteracyjne rozwiązanie:

from collections import deque 


def depth(d): 
    q = deque([d]) 
    q2 = deque() 
    max_depth = 0 
    while q: 
     curr_dict = q.popleft() 
     if isinstance(curr_dict, dict): 
      for di in curr_dict.itervalues(): 
       q2.append(di) 
     if not q: 
      q, q2 = q2, q 
      max_depth += 1 
    return max_depth 

print depth(None) 
print depth({}) 
print depth({"a": "b"}) 
print depth({"a": "b", "c": {"d": "e"}, "f": {"g": "h"}, "i": {"j": "k"}, "x": {}, "z": {} }) 
print depth({'a':1, 'b': {'c':{}}}) 
print depth({'foo': {'bar': {'baz': 0}, 'spam': {'ham': {'monty': 1}, 'eric': 'idle'}}, 'john': 'cleese'}) 
Powiązane problemy