2016-12-20 6 views
0

私は大きな値の辞書を作るために、後続の値を含む辞書のセットをお互いにループさせようとしています。 基本的に、リスト(辞書を含む)があり、これらのリストは辞書のリストを含む異なる辞書にまたがっている辞書です。Pythonの辞書のセットの再帰的なループ

datapage1 = {"events":{"data":[{"A":{"1_2": "2", 
            "1_3":{"data":[{"a_ORIGINAL":"1"}, 
                {"a_ORIGINAL":"2"}, 
                {"a_ORIGINAL":"3"}], 
              "sub_dir":{"location":"datapage11b"}}, 
            "1_4":"4", 
            "1_5":"5", 
            "1_6":"6",}}, 
         {"B":"2_1"}, 
         {"C":"3_1"}, 
         {"D":"4_1"}, 
         {"E":"5_1"}], 
       "sub_dir":{"location":"datapage2"}} } 


datapage2 = {"data":[{"F" : "FROMdata2"}, 
       {"G":"FROMdata2"}, 
       {"H":"FROMdata2"}, 
       {"I":"FROMdata2"}, 
       {"J":"FROMdata2"}], 
     "sub_dir":{"location": "datapage3"}} 


datapage3 = {"data":[{"K":"FROMdata3"}, 
       {"L":"FROMdata3"}, 
       {"M":{"FROMdata3": "1", 
            "13_2":{"data":[{"data3_ORIGINAL":"1"}, 
                {"data3_ORIGINAL":"2"}, 
                {"data3_ORIGINAL":"3"}], 
              "sub_dir":{"location":"datapage33b"}}, 
            "13_3":"3", 
            "13_4":"4", 
            "13_5":"5",}}, 
       {"N":"FROMdata3"}, 
       {"O":"FROMdata3"}], 
     "sub_dir":{"nolocation": "None"}} 

datapage11b = {"data":[{"FROMdata11b SUB_ADDED":"4"}, 
        {"FROMdata11b SUB_ADDED":"5"}, 
        {"FROMdata11b SUB_ADDED":"6"}], 
      "sub_dir":{"location":"datapage11c"}} 

datapage11c = {"data":[{"FROMdata11c SUB_ADDED":"7"}, 
        {"FROMdata11c SUB_ADDED":"8"}, 
        {"FROMdata11c SUB_ADDED":"9"}], 
      "sub_dir":{"location":"datapage33b"}} 

datapage33b = {"data":[{"FROMdata33b SUB_ADDED":"4"}, 
        {"FROMdata33b SUB_ADDED":"5"}, 
        {"FROMdata33b SUB_ADDED":"6"}], 
      "sub_dir":{"location":"datapage44c"}} 

datapage44c = {"data":[{"FROMdata44c SUB_ADDED":"1"}, 
        {"FROMdata44c SUB_ADDED":"2"}, 
        {"FROMdata44c SUB_ADDED":"3"}], 
      "sub_dir":{"nolocation":"None"}} 

は、基本的に各辞書は、リストが含まれてデータ -keyがあります:あなたは私が作った辞書の例を見つけることができます以下のよう

それは、おそらくかなり混乱します。このデータリストは、データ -key内の別の辞書に続いています。

sub_dir -keyは、リストを続行する場合は正しい辞書を指します。

私はこのサイトの他のソリューションを見て回帰ループをコンパイルしましたが、それは完全にではありません。

def findSubDict(v, prefix=''): 
    if isinstance(v, dict): 
     for k, v2 in v.items(): 
      if k == 'location': 
       borrow_dir = v2 
       upOne = prefix.replace("sub_dir", "data") 
       for item in eval(borrow_dir + "['data']"): 
        eval("datapage1" + upOne + ".append(item)") 
       while "location" in eval(borrow_dir + "['sub_dir']"): 
        borrow_dir = eval(borrow_dir + "['sub_dir']['location']") 
        for item in eval(borrow_dir + "['data']"): 
         eval("datapage1" + upOne + ".append(item)") 
      p2 = "{}['{}']".format(prefix, k) 
      findSubDict(v2, p2) 

    elif isinstance(v, list): 
     for i, v2 in enumerate(v): 
      p2 = "{}[{}]".format(prefix, i) 
      findSubDict(v2, p2) 

findSubDict(datapage1) 
pprint.pprint(datapage1) 

私はそれを実行してみてください、結果は一貫していない: はここに私のループです。たとえば、私はかなり多くの結果を得ていますが、複数回試してみると、ときどきevents['data'][12]['13_2']['data']のキーと値の一部が欠落していることに気付きました。

私の質問、そう

{'events': {'data': [{'A': {'1_2': '2', 
          '1_3': {'data': [{'a_ORIGINAL': '1'}, 
              {'a_ORIGINAL': '2'}, 
              {'a_ORIGINAL': '3'}, 
              {'FROMdata11b SUB_ADDED': '4'}, 
              {'FROMdata11b SUB_ADDED': '5'}, 
              {'FROMdata11b SUB_ADDED': '6'}, 
              {'FROMdata11c SUB_ADDED': '7'}, 
              {'FROMdata11c SUB_ADDED': '8'}, 
              {'FROMdata11c SUB_ADDED': '9'}, 
              {'FROMdata33b SUB_ADDED': '4'}, 
              {'FROMdata33b SUB_ADDED': '5'}, 
              {'FROMdata33b SUB_ADDED': '6'}, 
              {'FROMdata44c SUB_ADDED': '1'}, 
              {'FROMdata44c SUB_ADDED': '2'}, 
              {'FROMdata44c SUB_ADDED': '3'}], 
            'sub_dir': {'location': 'datapage11b'}}, 
          '1_4': '4', 
          '1_5': '5', 
          '1_6': '6'}}, 
        {'B': '2_1'}, 
        {'C': '3_1'}, 
        {'D': '4_1'}, 
        {'E': '5_1'}, 
        {'F': 'FROMdata2'}, 
        {'G': 'FROMdata2'}, 
        {'H': 'FROMdata2'}, 
        {'I': 'FROMdata2'}, 
        {'J': 'FROMdata2'}, 
        {'K': 'FROMdata3'}, 
        {'L': 'FROMdata3'}, 
        {'M': {'13_2': {'data': [{'data3_ORIGINAL': '1'}, 
               {'data3_ORIGINAL': '2'}, 
               {'data3_ORIGINAL': '3'}, 
             -----> {'FROMdata33b SUB_ADDED': '4'}, 
             -----> {'FROMdata33b SUB_ADDED': '5'}, 
             -----> {'FROMdata33b SUB_ADDED': '6'}, 
             -----> {'FROMdata44c SUB_ADDED': '1'}, 
             -----> {'FROMdata44c SUB_ADDED': '2'}, 
             -----> {'FROMdata44c SUB_ADDED': '3'}], 
            'sub_dir': {'location': 'datapage33b'}}, 
          '13_3': '3', 
          '13_4': '4', 
          '13_5': '5', 
          'FROMdata3': '1'}}, 
        {'N': 'FROMdata3'}, 
        {'O': 'FROMdata3'}], 
      'sub_dir': {'location': 'datapage2'}}} 

(私は行方不明のキーに "----->" と出力の&値を強調表示)である: "ですが、なぜでしょう?" おそらく言及する必要はありませんが、私の目標(もちろん)はすべてのキーと値を取得することです。 私は何度もコードをチェックしていますが、それだけを理解することはできません...

ご協力いただければ幸いです!

P.S.みんなにハッピーホリデー! :)

+2

私は混乱しています。あなたは正確に何をしようとしていますか? 'eval'への呼び出しは赤い旗です –

+0

ええ、私はそれがあると思った...:D 私は編集を行い、より明確にしようとします。 しかし、基本的には、最初の辞書(datapage1)をループし、他の辞書の値を指定した場所に追加します。いくつかの値を持つ別の辞書を指す "sub_dir/location"情報があります。このsub_dir/location -dictは、さらに多くの値を含む別のdictに進むことがあります。これらの値はすべて適切な場所にdatapage1-dictに追加する必要があります。 したがって、datapage1を通過してこれらのsub_dirを追加する再帰的ループ... – GPost

+0

P.S.私は '[sub_dir] [location]' - 値を辞書の場所として使用する他の方法を知らないので、 'eval'を使用しています... – GPost

答えて

1

私はいくつかのテストを行いましたが、そのうちの1つでは、元の辞書を修正しています...同じdictがdatapage33bとdatapage44cのように複数回使用される可能性があるため、

は、だから私はコピーで作業することを決定し、単に一度に処理sub_dir部品を保持しません。次のコードで一貫性のある結果を得た:

def process(dic): 
    cr = None 
    if not isinstance(dic, dict): 
     return dic 
    if 'data' in dic: 
     cr = {'data': [ process(d) for d in dic['data'] ] } 
    else: 
     cr = { k: process(dic[k]) for k in dic } 
    try: 
     temp = process(eval(dic['sub_dir']['location']))['data'] 
     cr['data'].extend(temp) 
    except KeyError: 
     pass 
    return cr 

しかしを注意してください:あなたの元のコードのように、この1つの用途をevalあなたはコントロールされていない入力では決して使用しないでください。

+0

**これは完全に機能しました!大変ありがとう@SergeBallesta !! ** ...しかし、私はまだ少し混乱しています。それで、矛盾を引き起こしたのは元の辞書の修正だったのでしょうか? また、 'eval'の頭に感謝します。私は 'eval'が使用するのが好ましい方法ではないことに気付きましたが、dictキーとして値を渡す方法はありますか? 私は最後の週末に解決策を探していましたが、これが働いたのはこれだけでした。 – GPost