简体   繁体   English

使用Python以点表示法打印唯一的JSON键

[英]Print unique JSON keys in dot notation using Python

I am trying to write a script that will print the unique keys of a JSON file in dot notation so as to quickly profile the structure. 我正在尝试编写一个脚本,以点表示法打印JSON文件的唯一键,以便快速分析结构。

For example let's say I have 'myfile.json' with the following format: 例如,假设我的'myfile.json'具有以下格式:

{
"a": "one",
"b": "two",
"c": {
    "d": "four",
    "e": "five",
    "f": [
        {
            "x": "six",
            "y": "seven"
        },
        {
            "x": "eight",
            "y": "nine"
        }
    ]
}

Running the following will produce a unique set of keys, but it is missing the lineage. 运行以下命令将生成一组唯一的键,但它缺少谱系。

import json
json_data = open("myfile.json")
jdata = json.load(json_data)

def get_keys(dl, keys_list):
    if isinstance(dl, dict):
        keys_list += dl.keys()
        map(lambda x: get_keys(x, keys_list), dl.values())
    elif isinstance(dl, list):
        map(lambda x: get_keys(x, keys_list), dl)

keys = []
get_keys(jdata, keys)

all_keys = list(set(keys))

print '\n'.join([str(x) for x in sorted(all_keys)])

The following output doesn't indicate that 'x', 'y' are nested within the 'f' array. 以下输出不表示'x','y'嵌套在'f'数组中。

a
b
c
d
e
f
x
y

I can't figure out how to loop through the nested structure to append the parent keys. 我无法弄清楚如何遍历嵌套结构以附加父键。

The ideal output would be: 理想的输出是:

a
b
c.d
c.e
c.f.x
c.f.y

I'd recommend using a recursive generator function, using the yield statement rather than building a list internally. 我建议使用递归生成器函数,使用yield语句而不是在内部构建列表。 In Python 2.6+, the following works: 在Python 2.6+中,以下工作原理:

import json
json_data = json.load(open("myfile.json"))

def walk_keys(obj, path=""):
    if isinstance(obj, dict):
        for k, v in obj.iteritems():
            for r in walk_keys(v, path + "." + k if path else k):
                yield r
    elif isinstance(obj, list):
        for i, v in enumerate(obj):
            s = "[" + str(i) + "]"
            for r in walk_keys(v, path + s if path else s):
                yield r
    else:
        yield path


for s in sorted(walk_keys(json_data)):
    print s

In Python 3.x, you can use yield from as syntactic sugar for recursive generation, as follows: 在Python 3.x中,您可以使用yield作为语法糖进行递归生成,如下所示:

import json
json_data = json.load(open("myfile.json"))

def walk_keys(obj, path=""):
    if isinstance(obj, dict):
        for k, v in obj.items():
            yield from walk_keys(v, path + "." + k if path else k)
    elif isinstance(obj, list):
        for i, v in enumerate(obj):
            s = "[" + str(i) + "]"
            yield from walk_keys(v, path + s if path else s)
    else:
        yield path


for s in sorted(walk_keys(json_data)):
    print(s)

Drawing off of MTADD's guidance I put together the following: 根据MTADD的指导,我将以下内容放在一起:

import json

json_file_path = "myfile.json"
json_data = json.load(open(json_file_path))

def walk_keys(obj, path = ""):
    if isinstance(obj, dict):
        for k, v in obj.iteritems():
            for r in walk_keys(v, path + "." + k if path else k):
                yield r
    elif isinstance(obj, list):
        for i, v in enumerate(obj):
            s = ""
            for r in walk_keys(v, path if path else s):
                yield r
    else:
        yield path

all_keys = list(set(walk_keys(json_data)))

print '\n'.join([str(x) for x in sorted(all_keys)])

The results match as expected 结果符合预期

a
b
c.d
c.e
c.f.x
c.f.y

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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