python迭代json文件,其中json结构和键值未知

时间:2017-03-12 16:52:00

标签: python json serialization deserialization getjson

考虑下面的示例JSON。

{
"widget": {
    "test": "on",
    "window": {
        "title": "myWidget1",
        "name": "main_window"
    },
    "image": {
        "src": "Images/wid1.png",
        "name": "wid1"
    }
},
"os":{
    "name": "ios"
}

}

考虑我们不知道JSON的结构和任何键的情况。我需要实现的是一个python函数,它遍历所有的键和子键并打印键。这只是通过知道JSON文件名,我应该能够迭代整个键和子键。 JSON可以是任何结构。我试过的是下面的。

JSON_PATH = "D:\workspace\python\sampleJSON.json"
os.path.expanduser(JSON_PATH)

def iterateAllKeys(e):
    for key in e.iterkeys():
        print key
        for child in key.get(key):
            iterateAllKeys(child)

with open(JSON_PATH) as data_file:    
    data = json.load(data_file)

iterateAllKeys(data)

这里,iterateAllKeys()函数应该打印JSON文件中存在的所有键。但是如果只存在外环,即

def iterateAllKeys(e):
    for key in e.iterkeys():
        print key

它将打印键"小部件"和" os"。但是,

def iterateAllKeys(e):
    for key in e.iterkeys():
        print key
        for child in key.get(key):
            iterateAllKeys(child)

返回错误 - AttributeError:' unicode'对象没有属性' get'。我的理解是 - 因为“孩子”的价值。不是dict对象,我们不能应用' key.get()'。但是有没有其他方法可以迭代JSON文件而不指定任何键名。谢谢。

3 个答案:

答案 0 :(得分:3)

您可以使用递归来迭代这样的多级词典:

def iter_dict(dic):
    for key in dic:
        print(key)
        if isinstance(dic[key], dict):
            iter_dict(dic[key])

迭代第一个字典的键并打印每个键,如果该项是dict类的实例,我们可以使用递归来迭代我们作为项目遇到的字典。

答案 1 :(得分:2)

你可以通过像flatten_json这样的辅助包来做到这一点。

pip install flatten_json

from flatten_json import flatten

for key in flatten(your_dict).keys():
    print(key)

输出:

widget_test
widget_window_title
widget_window_name
widget_image_src
widget_image_name
os_name

如果您只想显示没有完整路径的密钥,那么您可以这样做:

print(key.split('_')[-1])

答案 2 :(得分:2)

首先是你的上一个功能:

def iterateAllKeys(e):
    for key in e.iterkeys():
        print key
        for child in key.get(key):
            iterateAllKeys(child)

key只是字典的key_value。所以如果你应该使用e.get(key)或e [key]。

 for child in e.get(key):

现在这不会解决你的问题,一个解决方法是使用try除外,如下:

def iterateAllKeys(e):
    for key in e.iterkeys():
        print key
        try:
            iterateAllKeys(e[key])
        except:
            print "---SKIP---"

这可能不是最好的解决办法,但肯定有效。 使用您的数据,它将打印以下内容:

widget
test
---SKIP---
window
name
---SKIP---
title
---SKIP---
image
src
---SKIP---
name
---SKIP---
os
name
---SKIP---