2016-09-06 3 views
0

を働いていない私は、次のコードを持っている:パイソン - 再帰

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

'yield from parseDics(vals、' vals ') '? –

+0

あなたのコードは、キーが 'solve'か' vals'であるかどうかだけをチェックし、 'subsolve'をキーとする辞書項目に決して再帰しません。 – Dunes

答えて

1

実際には、再帰呼び出しの結果で何かを行う必要があります。値とyieldを使用しているので、おそらくそれを使用する必要があります。

1

のPython 3.4では、あなたは、Python 2のために、yield from parseDics(vals, 'vals')を使用することができます。

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

parseDicsが、それは発電機ですが、通常の関数ではありません。したがって、通常の関数ではなくジェネレータのように呼び出す必要があります。それ以外の場合は動作しません。 list(parseDicts(...))を呼び出すと、リストコンストラクタがparseDictsをジェネレータとして呼び出すため、最初の呼び出しが機能します。しかし、parseDictsの中では、再帰的にparseDictsを関数として呼び出そうとしますが、これはうまくいきません。

変更yield fromを使用するには、再帰呼び出しあなたは、Python 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]