2016-09-19 105 views
3

我有一個由嵌套列表和字典組成的結構。我想對每個元素應用 函數。如何做到沒有遞歸。訪問嵌套列表和字典中的所有元素而不遞歸

def visit(data, func): 
    if isinstance(data, dict): 
     for k, v in data.items(): 
      data[k] = visit(v, func) 
     return data 
    elif isinstance(data, list): 
     for i, v in enumerate(data): 
      data[i] = visit(v, func) 
     return data 
    else: 
     return func(data) 

的遞歸版本適用於小型的數據,但我打的RecursionError 異常時的數據是大的。

我找了一般的方法來消除遞歸,我發現那些依靠 第一轉化遞歸調用尾調用,我這個問題是 在我的例子遞歸調用是一個循環中。

+0

你會打的,它們嵌套超過1000個深層次的數據結構,這似乎是可笑的遞歸限制。我懷疑實際發生的情況是你的數據有周期。 –

+0

@ Zii8roZi爲什麼不直接遞增遞歸限制? 'import sys; sys.setrecursionlimit(100000)' – Frito

+0

你想實現什麼?列表和字典應該如何處理,因爲列表僅包含元素,而字典則提供鍵 - 值對。 – albert

回答

3

這種方法可行。儘管如此,我也同意Sven Marnach的觀點,如果你的嵌套正在打破遞歸限制,那麼絕對是腥意的。如果像斯文所猜測的那樣,你的數據有周期性,這種方法也會中斷。

data = [1,2, {'a':1, 'b':{'a':[1,2,3]}},3] 

def apply(data, f): 
    stack = [] 
    stack.append(data) 
    while stack: 
     data = stack.pop() 
     if isinstance(data, dict): 
      for k,v in data.items(): 
       if isinstance(v, (dict,list)): 
        stack.append(v) 
       else: 
        data[k] = f(v) 
     if isinstance(data, list): 
      for i,e in enumerate(data): 
       if isinstance(e, (dict,list)): 
        stack.append(e) 
       else: 
        data[i] = f(e) 

在解釋器shell:

$ python -i apply.py 
>>> apply(data, lambda x: x + 1) 
>>> data 
[2, 3, {'a': 2, 'b': {'a': [2, 3, 4]}}, 4] 
>>>