2016-03-14 12 views
8

Bảng:Tạo bãi json thứ bậc từ danh sách các từ điển trong 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), 

) 

Một loại có thể có nhiều trẻ em, nhưng chỉ có 1 phụ huynh. Tôi đã có danh sách các giá trị từ điển như sau bằng cách sử dụng CTE: ví dụ. Đối với id: 14, cha mẹ là 13 và đi qua từ cha mẹ 8-> 10-> 12-> 13-> 14, nơi phụ huynh 8 không có id mẹ.

[ 
    { 
     "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 
     ] 
    } 
    ] 

Tôi muốn để có được các thuộc tính của phụ huynh cũng nhúng như tiểu thể loại trong danh sách như:

{ 
    "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..... 
    ] 
} 

] Chú ý rằng 'PATH_INFO' đã bị xóa khỏi từ điển và mỗi id có được hiển thị với các chi tiết của nó. Tôi muốn json bãi với định dạng thụt lề trên. Làm thế nào để đi về? Sử dụng bình 0.10, python 2.7

Trả lời

1

Có một cách có thể chấp nhận được để thực hiện việc này với một số danh sách/hiểu thấu đáo.

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

Bạn có thể thực hiện nó trong mã python:

Cho chúng tôi có đối tượng json. Tôi đã chút thay đổi nó - thêm nút vắng mặt và quấn thành một đối tượng khi nó được yêu cầu của các đặc điểm kỹ thuật:

{ 
     "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 
      ] 
      } 
     ] 
    } 

Sau đó, bạn có thể sử dụng đoạn mã sau:

# 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'] 

Để chắc chắn bạn đang nhận được điều bạn cần:

>>> 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

mã pythonic cho việc này: đơn giản và dễ hiểu

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)) 
Các vấn đề liên quan