$ cat ~/articles/99 _

搜索元素在数组中的路径

作者:jaifire 2020-04-25 12:06 1286 阅读

写爬虫的时候,遇到一个很深的json数组,由于数据长度十分巨大,没有办法靠肉眼去找到某个值所在的路径,所以需要有一个算法,给定一个值,返回该值在数组中的所有路径

最初想用递归层层查找,可是递归只能操作一个值,所以一次只能查找一个路径,由不知道怎么把查找出来的路径给删除掉,所以用递归的办法失败了

def fff(data, path=[]):
    if type(data) is dict:
        for k, v in data.items():
            # print(k, v)
            path.append(k)
            return fff(v, path)
    elif type(data) is list:
        for idx, i in enumerate(data):
            # print(idx, i)
            path.append(idx)
            return fff(i, path)
    else:
        if 'browse' == data: # 想要搜索的字符
            print(data, path)
        # print(data, path)
        return path

p = fff(ddd)  # 想要把ddd中的p路径删除掉,然后再调用fff,可是不知道怎么删除 print(p)

后来想到把数组转成纯字典就好操作了,所以有了以下方法

class Tree:
    key = None  # 数组的键名,如果是数字就转成字符串
    val = None  # 数组的键值

    def init(self, data, key=None):         # 把数组转成树状结构,查找的时候每个分枝对比自己的val就好了         self.key = key         if type(data) is dict:             for k, v in data.items():                 setattr(self, k, Tree(v, k))         elif type(data) is list:             for idx, i in enumerate(data):                 setattr(self, str(idx), Tree(i, str(idx)))         else:             self.__val = data

    def search(self, val, path=''):         for i in self.dict:             # print(type(i), i)             if '_Tree' not in i:                 _t = getattr(self, i)                 _t.search(val, "{}/{}".format(path, _t.key))                 if _t.__val == val:                     print('搜索结果', val, path + '/' + _t.key)

ddd = [     {         "page": "browse",         "csn": "ZKiiXqySB5avlQSQ57OoDQ",         "rootVe": 3611,         'data': [             {                 "page": "browse",                 "csn": "ZKiiXqySB5avlQSQ57OoDQ",                 "rootVe": 3611,             }         ]     } ]

obj = Tree(ddd)

obj.search(3611)

 运行结果

搜索结果 3611 /0/rootVe 搜索结果 3611 /0/data/0/rootVe