2016-03-14 11 views
8

tabeli:Tworzenie hierarchicznej json zrzut z listy słownika w python

categories = Table("categories", metadata, 
        Column("id", Integer, primary_key=True), 
        Column("name", String), 
        Column("parent_id", Integer, ForeignKey("categories.id"), 
          CheckConstraint('id!=parent_id'), nullable=True), 

) 

Kategoria A może mieć wiele dzieci, ale tylko 1 rodzicem. Mam listę wartości słownika w następujący sposób za pomocą CTE: np. W przypadku identyfikatora: 14 rodzic ma 13 i przechodził z rodzica 8-> 10-> 12-> 13-> 14, gdzie rodzic 8 nie ma identyfikatora nadrzędnego.

[ 
    { 
     "id": 14, 
     "name": "cat14", 
     "parent_id": 13, 
     "path_info": [ 
     8, 
     10, 
     12, 
     13, 
     14 
     ] 
    }, 
    { 
     "id": 15, 
     "name": "cat15", 
     "parent_id": 13, 
     "path_info": [ 
     8, 
     10, 
     12, 
     13, 
     15 
     ] 
    } 
    ] 

chciałbym uzyskać atrybuty rodzica również osadzony w podkategorii na liście jako:

{ 
    "id": 14, 
    "name": "cat14", 
    "parent_id": 13, 
    "subcats": [ 
     { 
     "id: 8", 
     "name": "cat8", 
     "parent_id":null 
     }, 
     { 
     "id: 10", 
     "name": "cat10", 
     "parent_id":8 
     }, 
     { 
     "id: 12", 
     "name": "cat12", 
     "parent_id":10 
     }, 
     and similarly for ids 13 and 14..... 
    ] 
}, 
{ 
    "id": 15, 
    "name": "cat15", 
    "parent_id": 13, 
    "subcats": [ 
     { 
     "id: 8", 
     "name": "cat8", 
     "parent_id":null 
     }, 
     { 
     "id: 10", 
     "name": "cat10", 
     "parent_id":8 
     }, 
     { 
     "id: 12", 
     "name": "cat12", 
     "parent_id":10 
     }, 
     and similarly for ids 13, 14, 15..... 
    ] 
} 

] Zauważ, że „PATH_INFO” zostało usunięte ze słownika, a każdy identyfikator ma został wyświetlony ze szczegółowymi informacjami. Chcę json dumps z powyższym formatem z wcięciem. Jak to zrobić? Korzystanie kolby 0,10, Python 2.7

Odpowiedz

1

Jest to możliwy sposób na zrobienie tego przy użyciu kilku wyrażeń list/dict.

lst = [{"id": 14, "name": "cat14", "parent_id": 13, "path_info": [8, 10, 12, 13, 14]}, {"id": 15, "name": "cat15", "parent_id": 13, "path_info": [8, 10, 12, 13, 15]}] 

master_dct = { d['id'] : d for d in lst} 
for d in lst: 
    d['subcats'] = [{field : master_dct[i][field] for field in ['id', 'name', 'parent_id']} \ 
     for i in d['path_info'] if i in master_dct] 

import json 
with open('out.json', 'w') as f: 
    json.dump(lst, f) 
1

Można wykonać go w kodzie Pythona:

Biorąc pod uwagę, że mamy obiekt JSON. Mam nieco zmodyfikowany go - dodał nieobecnych węzły i zawinąć do obiektu, jak to jest wymagane przez specyfikację:

{ 
     "array": [ 
      { 
      "id": 14, 
      "name": "cat14", 
      "parent_id": 13, 
      "path_info": [ 
       8, 
       10, 
       12, 
       13, 
       14 
      ] 
      }, 
      { 
      "id": 15, 
      "name": "cat15", 
      "parent_id": 13, 
      "path_info": [ 
       8, 
       10, 
       12, 
       13, 
       15 
      ] 
      }, 
      { 
      "id": 13, 
      "name": "cat13", 
      "parent_id": 12, 
      "path_info": [ 
       8, 
       10, 
       12, 
       13 
      ] 
      }, 
     { 
      "id": 12, 
      "name": "cat12", 
      "parent_id": 10, 
      "path_info": [ 
       8, 
       10, 
       12 
      ] 
      }, 
      { 
      "id": 10, 
      "name": "cat10", 
      "parent_id": 8, 
      "path_info": [ 
       8, 
       10 
      ] 
      }, 
      { 
      "id": 8, 
      "name": "cat8", 
      "parent_id": null, 
      "path_info": [ 
       8 
      ] 
      } 
     ] 
    } 

Następnie można użyć następującego kodu:

# load data above from file 
    j=json.load(open('json_file_above.json')) # 

    # the array with real data we need 
    a=j['array'] 

    # auxiliary dict which have node identificators as keys and nodes as values 
    d={x['id']:x for x in a} 

    # here the magic begins :) 
    for x in a: 
     # add new key with list to each element 
     x['subcats'] = [ 
         # compose dict element for subcats 
         dict(id=i, name=d[i]['name'], parent_id=d[i]['parent_id']) 
         for 
         i 
         in [ 
          # we take path_info id list and 
          # cut off the first element - itself 
          y for y in x['path_info'][1:] 
          ] 
         ] 
     del x['path_info'] 

Aby mieć pewność, że są coraz rzecz trzeba:

>>> print(json.dumps(a, indent=True)) 
    [ 
    { 
     "name": "cat14", 
     "subcats": [ 
     { 
     "name": "cat10", 
     "id": 10, 
     "parent_id": 8 
     }, 
     { 
     "name": "cat12", 
     "id": 12, 
     "parent_id": 10 
     }, 
     { 
     "name": "cat13", 
     "id": 13, 
     "parent_id": 12 
     }, 
     { 
     "name": "cat14", 
     "id": 14, 
     "parent_id": 13 
     } 
     ], 
     "id": 14, 
     "parent_id": 13 
    }, 
    { 
     "name": "cat15", 
     "subcats": [ 
     { 
     "name": "cat10", 
     "id": 10, 
     "parent_id": 8 
     }, 
     { 
     "name": "cat12", 
     "id": 12, 
     "parent_id": 10 
     }, 
     { 
     "name": "cat13", 
     "id": 13, 
     "parent_id": 12 
     }, 
     { 
     "name": "cat15", 
     "id": 15, 
     "parent_id": 13 
     } 
     ], 
     "id": 15, 
     "parent_id": 13 
    }, 
    { 
     "name": "cat13", 
     "subcats": [ 
     { 
     "name": "cat10", 
     "id": 10, 
     "parent_id": 8 
     }, 
     { 
     "name": "cat12", 
     "id": 12, 
     "parent_id": 10 
     }, 
     { 
     "name": "cat13", 
     "id": 13, 
     "parent_id": 12 
     } 
     ], 
     "id": 13, 
     "parent_id": 12 
    }, 
    { 
     "name": "cat12", 
     "subcats": [ 
     { 
     "name": "cat10", 
     "id": 10, 
     "parent_id": 8 
     }, 
     { 
     "name": "cat12", 
     "id": 12, 
     "parent_id": 10 
     } 
     ], 
     "id": 12, 
     "parent_id": 10 
    }, 
    { 
     "name": "cat10", 
     "subcats": [ 
     { 
     "name": "cat10", 
     "id": 10, 
     "parent_id": 8 
     } 
     ], 
     "id": 10, 
     "parent_id": 8 
    }, 
    { 
     "name": "cat8", 
     "subcats": [], 
     "id": 8, 
     "parent_id": null 
    } 
    ] 
    >>> 
1

Kod pythonic do tego proste i nieskomplikowane

import json 
categories = [] #input 
def transform(category, child_node_id): 
    category['subcats'].append({ 
     'id': child_node_id, 
     'name': 'cat%s' % child_node_id, 
     'parent_id': category['id'] 
    }) 


for category in categories: 
    category['subcats'] = [] 
    [transform(category, child_node_id) for child_node_id in category['path_info']] 
    category.pop('path_info', None) 

print(json.dumps(categories, indent=4)) 
Powiązane problemy