2016-09-06 82 views
0

我有下面的代碼:Python的 - 遞歸不工作

d = {'init': 
     [{'solve': 
       [{'subsolve': 
         [{'vals': [{'Blade summary': 'asdf'}, 
            {'Blade summary': 'fdsa'}]}]}, 
        {'subsolve': 
         [{'vals': [{'Blade summary': 'ffff'}]}]}]}, 
     {'solve': 
       [{'subsolve': 
         [{'vals': 'bbbb'}]}]}]} 

def parseDics(lst, mainReg): 
    print('call') 
    for dic in lst: 
     for key, vals in dic.items(): 
      if key == mainReg: 
       if mainReg == 'vals': 
        yield vals 
       parseDics(vals, 'vals') 
      else: 
       parseDics(vals, mainReg) 



if __name__=='__main__': 
    pp.pprint(list(parseDics(d['init'], 'solve'))) 

函數本身是不完整的,但是這不是一個問題了。看來問題是,遞歸調用不起作用。

如果我現在嘗試運行它,我會得到僅此輸出:

call 
[] 

所以函數被調用一次。當我嘗試進入嵌套函數調用(我正在使用PyCharm)時,我簡直不能夠和函數調用是「過度的」。

我在做什麼錯?爲什麼不是我遞歸調用的函數?

+0

'parseDics(vals,'vals')'的產量? –

+0

你的代碼只檢查鍵是否爲'solve'或'vals',它永遠不會遞歸到具有'subsolve'作爲鍵的字典項目中。 – Dunes

回答

1

你需要實際做一些你的遞歸調用的結果。由於您使用的值是yield,因此您可能也需要使用它。

1

在Python 3.4,你可以使用yield from parseDics(vals, 'vals'),爲Python 2:

for val in parseDics(vals, 'vals'): 
    yield val 
2

parseDics不是普通的功能,它是一臺發電機。所以你需要把它稱爲一個生成器,而不是一個普通的函數,否則它將無法工作。第一個調用起作用,因爲當你調用list(parseDicts(...))時,列表構造函數調用parseDicts作爲生成器。但是在parseDicts中,您嘗試以遞歸方式調用parseDicts作爲函數,這不起作用。

更改遞歸調用,如果你正在使用Python中使用yield from 3.3+:

def parseDics(lst, mainReg): 
    print('call') 
    for dic in lst: 
     for key, vals in dic.items(): 
      if key == mainReg: 
       if mainReg == 'vals': 
        yield vals 
       yield from parseDics(vals, 'vals') 
      else: 
       yield from parseDics(vals, mainReg) 

對於舊版本的Python,你需要遍歷的遞歸調用和產生每個創造價值:

def parseDics(lst, mainReg): 
    print('call') 
    for dic in lst: 
     for key, vals in dic.items(): 
      if key == mainReg: 
       if mainReg == 'vals': 
        yield vals 
       for val in parseDics(vals, 'vals'): 
        yield val 
      else: 
       for val in parseDics(vals, mainReg): 
        yield val 

作爲函數調用生成器只會創建生成器,它不會運行它。例如:

>>> def my_gen(): 
    print("my_gen()") 
    for i in range(5): 
     print(i) 
     yield i 

>>> my_gen() 
<generator object my_gen at 0x00000000045B6B48> 

>>> list(my_gen()) 
my_gen() 
0 
1 
2 
3 
4 
[0, 1, 2, 3, 4]