2010-03-26 51 views

回答

5

@哈佛的遞歸解決方案很可能將是OK ......除非嵌套的水平過高,然後你會得到一個RuntimeError: maximum recursion depth exceeded。爲了解決這個問題,你可以使用通常的技術來去除遞歸:保留你自己的一堆項目來檢查(作爲你的控制列表)。即:

def find_key_nonrecursive(adict, key): 
    stack = [adict] 
    while stack: 
    d = stack.pop() 
    if key in d: 
     return d[key] 
    for k, v in d.iteritems(): 
     if isinstance(v, dict): 
     stack.append(v) 

這裏的邏輯是相當接近的遞歸答案(除了以正確的方式;-)爲dict檢查,具有明顯的例外是遞歸調用被替換爲while環和.pop.append在顯式棧列表上的操作,stack

+0

你確切地知道最大遞歸深度是什麼嗎?從我所瞭解的情況來看,它至少要嵌套100層,但我並不完全確定。 – 2010-03-26 15:43:27

+0

@Goose Bumper:'import sys; sys.getrecursionlimit()'。另外,'sys.setrecursionlimit()' – gorsky 2010-03-26 17:09:38

+0

@gorsky:謝謝!對於每個人來說,我的電腦上的遞歸限制是1000。 – 2010-03-26 17:24:59

2

(使你的數據結構中的一些亂撞......)

就做遞歸:

def findkey(d, key): 
    if key in d: return d[key] 
    for k,subdict in d.iteritems(): 
     val = findkey(subdict, key) 
     if val: return val 
+2

如果在遞歸過程中遇到任何本身不是字典的值,則此方法將嘗試將其索引或對該非字典調用iteritems,從而失敗得非常特殊。 – 2010-03-26 14:45:06

0

只是遍歷字典和對底部檢查鍵(注意評論「找不到」價值)。

def find_key_recursive(d, key): 
    if key in d: 
    return d[key] 
    for k, v in d.iteritems(): 
    if type(v) is dict: # Only recurse if we hit a dict value 
     value = find_key_recursive(v, key) 
     if value: 
     return value 
    # You may want to return something else than the implicit None here (and change the tests above) if None is an expected value 
+0

這不是檢查對象類型的方法。 @jathanism:以及使用遞歸函數的其他可能方式是什麼? – SilentGhost 2010-03-26 11:09:37

+0

@SilentGhost更新使用比較合適的就是檢查。 – 2010-03-26 11:12:56

+1

嗯......而不是'type(v)'是'dict',你不應該使用'instanceof(v,dict)'?前者不接受'dict'的子類。另外,如果您檢查是否存在'__contains__',那麼您的代碼也會接受支持「in」運算符的其他對象,而不僅僅是dicts。 – 2010-03-26 11:21:10