2016-09-19 4 views
1

の問題 - 階層/複数のネストされたdictsにdictsのリストを変換する:のpython - 現在、私はこれらの入力を持って受注

query = [{'id': 1, 'desc': 'desc_father', 'parent_id': None} 
     ,{'id': 2, 'desc': 'desc_child_1', 'parent_id': 10} 
     ,{'id': 3, 'desc': 'desc_child_2', 'parent_id': 2} 
     ,{'id': 4, 'desc': 'desc_child_5', 'parent_id': 5} 
     ,{'id': 5, 'desc': 'desc_child_6', 'parent_id': 6} 
     ,{'id': 6, 'desc': 'desc_child_1', 'parent_id': 1}] 

は、これは私の再帰関数である:

def recursive(parent_list, child_dict, parent_id): 
    for l in parent_list: 
     if parent_id in l.values(): 
      if 'children' not in l: 
       l['children'] = [] 
      l['children'].append(child_dict) 
      break 
     else: 
      for i in l: 
       if isinstance(l[i], list): 
        recursive(d[i], child_dict, parent_id) 
    return parent_list 

これは私のメインのコードです:

results = [] 
for q in query: 
    dict_item = {} 
    dict_item['id'] = q['id'] 
    dict_item['desc'] = q['desc'] 
    if q['parent_id'] is None: 
     results.append(dict_item) 
    else: 
     results= recursive(results, dict_item, q['parent_id']) 
return results 

ので、上記のデータとコードで、私は以下のように結果を持っています。

[{ 
     'desc' : 'desc_father', 
     'id' : 1, 
     'children' : [{ 
       'desc' : 'desc_child_1', 
       'id' : 2, 
       'children' : [{ 
         'desc' : 'desc_child_2', 
         'id' : 3 
        } 
       ] 
      }, { 
       'desc' : 'desc_child_1', 
       'id' : 6 
      } 
     ] 
    } 
] 

あなたがループの中に、これらの項目の親がまだ作成されていないので(id = 5 & id = 6を持つアイテムを)id = 4id = 5を持つアイテムが不足して見ることができたので、この結果はあります。私は子供の前に父親の項目を作成するためにリストを前後にどのようにトラバースするかわからないので、この問題を修正するのが難しいです。ヘルプは高く評価されます。前もって感謝します。

を更新し

私はid = 2とアイテムである私のクエリのための一つのケースに追加している私たちが持っていないので、この時間は、項目は、10(parent_id = 10)にそのPARENT_IDを更新しています返品の結果でid = 10を親として持つので、このid = 2アイテムもルートになります。

私の新しいコードはScott Hunterのガイダンスに基づいていますが、まだ動作させることができませんでした。私はどこか誤解している必要があります:

new_dict = {} 
for q in query: 
    q['Children'] = [] 
    new_dict[q['id']] = q 

for k, v in new_dict.iteritems(): 
    print k, v 
    if v['parent_id'] is not None and v['parent_id'] in new_dict: 
     new_dict[k]['Children'].append(v) 

print new_dict 

が更新-2

を今私は以下のコードを参照してください、スコット・ハンターの提案に基づいて、それが動作するようにします。しかし、コードはあまりにも多くのために醜いように見える、とにかく私はこれを完璧にすることができますか?あなたのサポートのために多くのおかげで、もう一つのステップとそれが行われます!

new_dict = {} 

for q in query: 
    q['children'] = [] 
    q['parent'] = 1 
    new_dict[q['id']] = q 

for k, v in new_dict.iteritems(): 
    p_id = v['parent_id'] 
    for kk, vv in new_dict.iteritems(): 
     if kk == p_id: 
      v['parent'] = 0 
      vv['children'].append(v) 

results = [] 

for d_id, d_item in new_dict.iteritems(): 
    if d_item['parent'] == 1: 
     results.append(d_item) 

print results 
+0

なぜ 'v'を自分の子供の1人にしていますか? –

+0

こんにちは@ScottHunter、私はそれを働かせるようにしました。私のコードを見直してください。ありがとうございました。 – Leo

答えて

2

これは再帰を必要としません。

最初に、idをキーにして各アイテムに1つのノードの辞書を作成します。ノードには子の空のリストが含まれています。次に、その辞書をスキャンして、各ノードを親の子供のリストに追加します(親がNoneのものをスキップします)。このスキャンが完了すると、ルートではないすべてのノードがその親の子リストに置かれ、すべてのツリーが完成します。

forrestのルートは、親に対してNoneのノードです。

+0

あなたの答えは@Scott Hunterに感謝します。残念ながら私はあなたの答えをかなり理解できません。私がそれをよりよく理解できるように詳しく教えてもらえますか?あなたの答えによれば、子ノードは依然として父ノードという結果になる可能性がありますが、最初のレベルでは各ツリーの父のみが必要です。私のサンプル入力には1つの父親ノードしかありませんが、実際には 'parent_id:None'で複数の父親ノードが存在する可能性があります – Leo

+0

更新された回答をありがとうが、コードスニペットはありますか?私はこれに数時間苦労してきました。あなたの答えに基づいて、私はレベル3以上を作ることができませんでした。彼らはすべてレベル2に落ちます。ありがとう。 – Leo

+0

更新されたコードを投稿してください。 –

1

これが私の解決策のようになります。

#! /usr/bin/env python3 
from pprint import pprint 
query = [{'id': 1, 'desc': 'desc_father', 'parent_id': None} 
     ,{'id': 2, 'desc': 'desc_child_1', 'parent_id': 1} 
     ,{'id': 3, 'desc': 'desc_child_2', 'parent_id': 2} 
     ,{'id': 4, 'desc': 'desc_child_5', 'parent_id': 5} 
     ,{'id': 5, 'desc': 'desc_child_6', 'parent_id': 6} 
     ,{'id': 6, 'desc': 'desc_child_1', 'parent_id': 1}] 


def rec(query, parent): 
    parent['children'] = [] 
    for item in query: 
     if item['parent_id'] == parent['id']: 
      parent['children'].append(item) 
      rec(query, item) 


root = {'id': None} 
rec(query, root) 

pprint(root, indent=4) 

それは私に出力を提供します(キーが故障しているが、それはあなたが辞書を使用するときあなたが得るものです)

[email protected]:~/Dev/random$ python recursion_tree.py 
{ 'children': [ { 'children': [ { 'children': [], 
              'desc': 'desc_child_2', 
              'id': 3, 
              'parent_id': 2}], 
         'desc': 'desc_child_1', 
         'id': 2, 
         'parent_id': 1}, 
        { 'children': [ { 'children': [ { 'children': [ ], 
                   'desc': 'desc_child_5', 
                   'id': 4, 
                   'parent_id': 5}], 
              'desc': 'desc_child_6', 
              'id': 5, 
              'parent_id': 6}], 
         'desc': 'desc_child_1', 
         'id': 6, 
         'parent_id': 1}], 
    'desc': 'desc_father', 
    'id': 1, 
    'parent_id': None} 

これがなければなりません複数のルートノードで作業することもできます(ただし、上部にはIDがNoneのダミーノードがあります)

関連する問題