我想解析一个 JSON 文件并获取包含访问 key 所需的所有路径的完整列表。如果我们使用keys方法,我们会得到单个键的列表,但不会得到访问数据所需的分层键的完整列表。
因此,如果给出这样的数据
data = {
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
我可以返回一个如下所示的列表,其中包含 key 的所有完整路径。
[['glossary']['title'],['glossary']['GlossDiv']...]
读取和访问元素没问题。为了达到结果,我尝试使用这个SO答案Access nested dictionary items via a list of keys
我不太明白它是如何工作的,它只返回单词“glossary”。
这是我的代码。我使用 ChainMap 因为它可以更轻松地将 json 转换为字典并轻松访问 key 。
import json
from collections import ChainMap
from functools import reduce
import operator
myDataChained = ChainMap(data)
def getFromDict(data):
return reduce(operator.getitem, data)
Json_Paths = getFromDict(myDataChained)
print(Json_Paths)
最佳答案
您不能使用与链接答案中相同的技术来执行相反的操作 - 您没有预先通过 functools.reduce()/operator.getitem()
组合遍历的路径信息- 您正在尝试获取该信息,即标准化/扁平化您的字典结构。
为此,您必须迭代整个结构并收集数据中的所有可能的路径,例如:
import collections
def get_paths(source):
paths = []
if isinstance(source, collections.MutableMapping): # found a dict-like structure...
for k, v in source.items(): # iterate over it; Python 2.x: source.iteritems()
paths.append([k]) # add the current child path
paths += [[k] + x for x in get_paths(v)] # get sub-paths, extend with the current
# else, check if a list-like structure, remove if you don't want list paths included
elif isinstance(source, collections.Sequence) and not isinstance(source, str):
# Python 2.x: use basestring instead of str ^
for i, v in enumerate(source):
paths.append([i])
paths += [[i] + x for x in get_paths(v)] # get sub-paths, extend with the current
return paths
现在,如果您通过它运行您的数据
:
data = {
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages...",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
paths = get_paths(data)
您将获得包含以下内容的路径
:
[['glossary'], ['glossary', 'title'], ['glossary', 'GlossDiv'], ['glossary', 'GlossDiv', 'title'], ['glossary', 'GlossDiv', 'GlossList'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'ID'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'SortAs'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossTerm'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'Acronym'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'Abbrev'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'para'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'GlossSeeAlso'], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'GlossSeeAlso', 0], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'GlossSeeAlso', 1], ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossSee']]
您可以将其中任何一个输入到 functools.reduce()/operator.getitem()
组合中来获取目标值。
关于python 获取 json 键作为完整路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51488240/