2017-07-21 9 views
0

ネストされたpython辞書とリストの中の目標値のパスを見つける問題があります。 たとえば、私は以下のdictを持っており、私の目標値は "blah blah blah"です。ネストされたpython辞書とリストの中の目標値のパスを見つけよう

{ "id" : "abcde", 
    "key1" : "blah", 
    "key2" : "blah blah", 
    "nestedlist" : [ 
    { "id" : "qwerty", 
     "nestednestedlist" : [ 
     { "id" : "xyz", 
      "keyA" : "blah blah blah" }, 
     { "id" : "fghi", 
      "keyZ" : "blah blah blah" }], 
     "anothernestednestedlist" : [ 
     { "id" : "asdf", 
      "keyQ" : "blah blah" }, 
     { "id" : "yuiop", 
      "keyW" : "blah" }] } ] } 

私が得たいのは、入れ子になった辞書とリストのこの値のパスです。 「nestedlist」 - 「nestednestedlist」 - 「芥屋」

私はFind all occurrences of a key in nested python dictionaries and lists から、このコードを発見し、いくつかの変更を行わ:

def find(key,dic_name): 
    if isinstance(dic_name, dict): 
     for k,v in dic_name.items():   
      if k == 'name' and v == key: 
       yield v 
      elif isinstance(v,dict): 
       for result in find(key,v): 
        yield result 
      elif isinstance(v,list): 
       for d in v: 
        for result in find(key,d): 
         yield result 

をしかし、それは結果だけでは目標値ではなく、パスを取得することができます。 誰も助けることができますか?おかげでたくさんの

+0

[this](https://stackoverflow.com/a/41778581/4014959) –

+1

[ネストされた辞書をトラバースしてPythonでパスを取得しますか?](https://stackoverflow.com/questions/11929904/traverse-a-nested-dictionary-and-get-the-path-in-python) – trincot

答えて

1

利回りにあなたがリンクしたコードのマイナーチェンジ結果:あなたの入力のための

def fun(dct, value, path=()): 

    for key, val in dct.items(): 
     if val == value: 
      yield path + (key,) 
    for key, lst in dct.items(): 
     if isinstance(lst, list): 
      for item in lst: 
       for pth in fun(item, value, path + (key,)): 
        yield pth 

:あなたのコメントの後

for item in fun(dct, value='blah blah blah'): 
    print(item) 

# ('nestedlist', 'nestednestedlist', 'keyA') 
# ('nestedlist', 'nestednestedlist', 'keyZ') 

更新:のマイナーチェンジコードはあなたが望むようにすることができます:

def fun(dct, value, path=()): 

    for key, val in dct.items(): 
     if val == value: 
      yield path + (val,) 
    for key, lst in dct.items(): 
     if isinstance(lst, list): 
      for item in lst: 
       for pth in fun(item, value, path + (dct['id'], key,)): 
        yield pth 

例:

for item in fun(dct, value='xyz'): 
    print(item) 
# ('abcde', 'nestedlist', 'qwerty', 'nestednestedlist', 'xyz') 
+0

ありがとうございました。別の質問をすることができますか?今回は別のパスがあれば、 "nestedlist" - "nestednestedlist" - "keyA"のようなキーパスは必要ありません。代わりに、ネストされたリストのキーとパス。同じ例、私の目標値 "xyz"、そして望む結果は 'abcde' - 'nestedlist' - 'qwerty' - 'nestednestedlist' - 'xyz' –

+0

@RuiHuang:更新を掲載しました。トリックをすることを期待して... –

+0

それは完璧に動作します!ありがとう! –

関連する問題