简体   繁体   中英

Finding paths in a json tree in python

I have a json tree of the form

{"reply": 0, "id": 30, "children": [{"reply": 0, "id": 451, "children": []}, {"reply": 0, "id": 307, "children": []}, {"reply": 0, "id": 276, "children": []}, {"reply": 0, "id": 253, "children": []}]}

I want to get all the paths starting from root to the leaf of the json tree. For this I am using

import json
f=open('tree_json','r')
def paths(tree, cur=()):
         if not tree:
            yield cur
         else:
            for n, s in tree.items():
                for path in paths(s, cur+(n,)):
                   yield path
for line in f:
    tree=json.loads(line)
   print list(paths(tree,(0,)))

But, I am not able to print the paths in a tree. The output I want is: {30,451},{30,307},{30,276}. I am getting

    for n, s in tree.items():
     AttributeError: 'int' object has no attribute 'items'

There are several problems with your code, but the "error" you were getting isn't an error; it's the value returned by path(tree, 0) , which is a generator. You need to wrap it in list() to force it to evaluate itself. That said, if you do that, you're going to run into several bugs. And even if you fix the surface bugs, your code isn't going to give you the result you want.

This code will do what you're trying to do:

import pprint


def paths(tree):
    if not tree['children']:
        yield (tree['id'],)
    else:
        for child in tree['children']:
            for descendant in paths(child):
                yield (tree['id'],) + descendant

tree = {
    'reply': 0,
    'id': 30,
    'children': [
        {'reply': 0, 'id': 451, 'children': []},
        {'reply': 0, 'id': 307, 'children': []},
        {'reply': 0, 'id': 276, 'children': []},
        {'reply': 0, 'id': 253, 'children': [
            {'reply': 0, 'id': 600, 'children': []},
            {'reply': 0, 'id': 700, 'children': []},
            {'reply': 0, 'id': 800, 'children': []},
            {'reply': 0, 'id': 900, 'children': []},
        ]}
        ]
    }

pprint.pprint(list(paths(tree)))

Output:

[(30, 451),
 (30, 307),
 (30, 276),
 (30, 253, 600),
 (30, 253, 700),
 (30, 253, 800),
 (30, 253, 900)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM