2017-06-10 9 views
1

;で区切られたデータに基づいてJSONファイルを作成するには、次のコードがあります。コレクションから インポートCSV defaultdictサイズをJSONに追加

def ctree(): 
    """ One of the python gems. Making possible to have dynamic tree structure. 
    """ 
    return defaultdict(ctree) 


def build_leaf(name, leaf): 
    """ Recursive function to build desired custom tree structure 
    """ 
    res = {"name": name} 

    # add children node if the leaf actually has any children 
    if len(leaf.keys()) > 0: 
     res["children"] = [build_leaf(k, v) for k, v in leaf.items()] 

    return res 


def main(delimter): 
    tree = ctree() 
    text = """ 
    something;cookie;chocolat 
    something;cookie;milk 
    something;gains;bread 
    anything;protein;chicken 
    """ 
    rows = [row.strip().split(delimter) for row in text.split("\n")] 
    for row in rows: 
     if row: 
      leaf = tree[row[0]] 
      for cid in range(1, len(row)): 
       leaf = leaf[row[cid]] 

    # building a custom tree structure 
    res = [] 
    for name, leaf in tree.items(): 
     res.append(build_leaf(name, leaf)) 

    # printing results into the terminal 
    import json 
    print(json.dumps(res)) 


# so let's roll 
main(";") 

(ソース:Convert csv to JSON tree structure?)をインポートこれは、この出力を生成します

を:

[ 
    { 
    "name": "" 
    }, 
    { 
    "name": "something", 
    "children": [ 
     { 
     "name": "cookie", 
     "children": [ 
      { 
      "name": "chocolat" 
      }, 
      { 
      "name": "milk" 
      } 
     ] 
     }, 
     { 
     "name": "gains", 
     "children": [ 
      { 
      "name": "bread" 
      } 
     ] 
     } 
    ] 
    }, 
    { 
    "name": "anything", 
    "children": [ 
     { 
     "name": "protein", 
     "children": [ 
      { 
      "name": "chicken" 
      } 
     ] 
     } 
    ] 
    } 
] 

しかし私は, "size" : 100をinlcudeしたいので、私は持っていますこのような出力:

[ 
    { 
    "name": "" 
    }, 
    { 
    "name": "something", 
    "children": [ 
     { 
     "name": "cookie", 
     "children": [ 
      { 
      "name": "chocolat", "size" : 100 
      }, 
      { 
      "name": "milk", "size" : 100 
      } 
     ] 
     }, 
     { 
etc. 

したがって、3rdレイヤーにアイテムが追加されている場合は、実際には, "size" : 100を追加する必要があります。上記のような再帰を使用してこれが可能なのかどうか疑問に思っていますか?または、現在のレイヤーを「覚えている」ことができるネストされたループに変更する必要がありますか?もし再帰を使っている間にこれを達成するにはどうすればいいのですか?

+2

'build_leaf()'関数に別のパラメータを追加することができます。最初の実行では、0を渡します(Pythonにパラメータのデフォルト値があるかどうかはわかりませんが、これは完全な使い方になります)。 – Markaos

答えて

1

Markaosはコメントの中で言及しているように、各ディックに余分なキーと値のペアをいつ追加するかを知るためにはres["children"]。あなたはmainbuild_leafへの呼び出しを変更する必要はありませんので、私は、depthゼロのデフォルト値を与えてくれた

def build_leaf(name, leaf, depth=0): 
    """ Recursive function to build desired custom tree structure 
    """ 
    res = {"name": name} 
    depth += 1 

    # add children node if the leaf actually has any children 
    if len(leaf.keys()) > 0: 
     lst = [build_leaf(k, v, depth) for k, v in leaf.items()] 
     if depth >= 2: 
      for d in lst: 
       d['size'] = 100 
     res["children"] = lst  
    return res 

例えば、。

結果JSONは次のようになります(よりコンパクトな出力を生成するためにカスタムエンコーダを使用しました)。

[ 
    {"name": ""}, 
    { 
    "name": "something", 
    "children": [ 
     { 
     "name": "cookie", 
     "children": [ 
      {"name": "chocolat", "size": 100}, 
      {"name": "milk", "size": 100} 
     ] 
     }, 
     { 
     "name": "gains", 
     "children": [ 
      {"name": "bread", "size": 100} 
     ] 
     } 
    ] 
    }, 
    { 
    "name": "anything", 
    "children": [ 
     { 
     "name": "protein", 
     "children": [ 
      {"name": "chicken", "size": 100} 
     ] 
     } 
    ] 
    } 
] 
+0

ハハ私はちょうどマルカオスのコメントを書こうとしていた、よかった! – CodeNoob

関連する問題