python 获取 json 键作为完整路径

标签 python

我想解析一个 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/

相关文章:

python - 当原始矩阵具有奇数第二个索引时,为什么 NumPy 的 rfft2 的 irfft2 会导致矩阵少一列?

python - Python素数检查

python - 有没有一种优雅的方法来跟踪 Python 中的连接项集?

Python 脚本通过手术将一个 JSON 字段替换为另一个字段

python - 是否可以让 Python 自动检测动态库中的函数?

python - 在子类化 collections.MutableSequence 时如何实现 __delitem__?

python - Plotly:plotly 表达遵循什么颜色循环?

python - 为什么 PyCrypto 不允许使用私钥编码和使用公钥解码来验证发送者身份

python - 字符串比较如何在 python 上工作?

python - 属性错误: module 'tensorflow' has no attribute 'lite' in Keras model to Tensorflow Lite convertion - Python