访问json树的叶子

时间:2015-03-14 16:04:00

标签: json python-2.7

我有一个表格的JSON文件:

{"id":442500000116137984, "reply":0, "children":[{"id":442502378957201408, "reply":0, "children":[]}]}
{"id":442500001084612608, "reply":0, "children":[{"id":442500145871990784, "reply":1, "children":[{"id":442500258421952512, "reply":1, "children":[]}]}]}
{"id":442500000258342912, "reply":0, "children":[{"id":442500636668489728, "reply":0, "children":[]}]}

在这个行中,每行代表一个单独的树。现在我想去每棵树的树叶做一些事情,基本上是

import json
f = open("file", 'r')
for line in f:
    tree = json.loads(line)
    #somehow walk through the tree and find leaves
    if isLeaf(child):
        print "Reached Leaf"

如何浏览此树对象以检测所有树叶?

3 个答案:

答案 0 :(得分:3)

这应该有用。

import json
f = open("file", 'r')

leafArray = []

def parseTree(obj):
    if len(obj["children"]) == 0:
        leafArray.append(obj)
    else:
        for child in obj["children"]:
            parseTree(child)

for line in f:
    global leafArray
    leafArray = []
    tree = json.loads(line.strip())
    parseTree(tree) 
    #somehow walk through the tree and find leaves
    print ""
    for each in leafArray:
        print each

答案 1 :(得分:1)

你知道,我曾经不得不用JSON处理很多超媒体对象,所以我写了this library。问题是我事先并不知道树木的深度,所以我需要能够四处搜索并得到我称之为“路径”(用于到达树叶的一组键/索引)和值。

无论如何,你可以挖掘它的想法(我只为Python3.3 +编写它,但是here's the method inside a class that would do what you want)。

基本的想法是你走在树上并检查你遇到的对象,如果你得到更多的词典(甚至在列表中),你会更深入地陷入困境(我发现更容易把它写成递归生成器,主要是通过子类化collections.MutableMapping并使用自定义enumerate创建类。

你跟踪你沿途的路径,一旦你得到的值不值得进一步探索(它不是dictlist),那么你屈服你的路径和价值:

def enumerate(self, path=None):
    """Iterate through the PelicanJson object yielding 1) the full path to
    each value and 2) the value itself at that path.
    """
    if path is None:
    path = []
    for k, v in self.store.items():
        current_path = path[:]
        current_path.append(k)

        if isinstance(v, PelicanJson):
            yield from v.enumerate(path=current_path)
        elif isinstance(v, list):
            for idx, list_item in enumerate(v):
                list_path = current_path[:]
                list_path.append(idx)
                if isinstance(list_item, PelicanJson):
                    yield from list_item.enumerate(path=list_path)
                else:
                    yield list_path, list_item
        else:
            yield current_path, v

因为这是专门用于Python3的,它利用了yield from之类的东西,所以它不适用于你(我当然不是要提供我的解决方案作为唯一的解决方案) )。就个人而言,我对在各种函数中重复使用大量逻辑感到沮丧,因此编写这个库为我节省了大量工作,我可以回过头来处理我必须处理的超媒体API。#/ p>


答案 2 :(得分:0)

你可以这样做。 (我不知道python的语法)。

temp = tree #Your JSON object in each line
while (temp.children ! = []){
    temp = temp.children;
}

你的临时现在将成为叶子。