【问题标题】:How to get the parent keypath in json file?如何获取 json 文件中的父键路径?
【发布时间】:2018-02-14 16:58:06
【问题描述】:

在python中我们可以得到一个键的父键路径吗,我的json看起来像下面.. 例如,如果我输入 a1:它应该给出:PROJ1/LOB1。 list[] 中的所有键都是唯一的

{
    'PROJ1': {
        u'LOB1': [u'a1', u'a2'],
        u'LOb2': [u'v1', u'v2'],
        u'LOBA': [u'o1', u'oa', u'o2', u'o3'],
        u'LOBX': [u'n1', u'n2'],
        u'LOB': [u'b1', u'b2']
    },
  'PROJ12': {
        u'LOBa': [u'aa1', u'aa2'],
        u'LOBX': [u'vx1', u'vx2']
    },
}

我在另一个线程上发现了这个,但它不适用于上述数据。失败:unhashable type: 'list'

def keypaths(myDict):
    for key, value in myDict.items():
        if isinstance(value, collections.Mapping):
            for subkey, subvalue in self.keypaths(value):
                yield [key] + subkey, subvalue
        else:
            yield [key], value

reverse_dict = {value: keypath for keypath, value in keypaths(example_dict)}

【问题讨论】:

  • 您的数据在代码中运行良好。你在哪里得到错误?
  • @Idlehands 我忘了添加这一行:reverse_dict = {value: keypath for keypath, value in keypaths(example_dict)}
  • 您的值为listdicts 不能接受此数据类型作为键。可以通过使用str(value) 来制作list 的字符串表示,然后dict 将接受它作为键,但我不确定这是否是您想要实现的。
  • 我正在尝试获取密钥的密钥路径,如果我输入 a1:它应该给出:PROJ1/LOB1。 list[] 中的所有键都是唯一的
  • 什么应该给出:PROJ1/LOB1?创建反向字典与输入 1 并获得期望结果(来自 something)有什么关系?

标签: python json python-2.7 data-structures


【解决方案1】:

您需要向下钻取返回值的lists 以获取每个a1a2...等。您可以对keypaths 函数进行小修改以翻转键/返回值:

import collections

sample = {
    'PROJ1': {
        u'LOB1': [u'a1', u'a2'],
        u'LOb2': [u'v1', u'v2'],
        u'LOBA': [u'o1', u'oa', u'o2', u'o3'],
        u'LOBX': [u'n1', u'n2'],
        u'LOB': [u'b1', u'b2']
    },
    'PROJ12': {
        u'LOBa': [u'aa1', u'aa2'],
        u'LOBX': [u'vx1', u'vx2']
    },
}

def keypaths(myDict):
    for key, value in myDict.items():
        if isinstance(value, collections.Mapping):
            for subvalue, subkey in keypaths(value):
                yield subvalue, [key] + subkey
        elif isinstance(value,list):
            for i in value:
                yield i, [key]
        else:
            yield value, [key]

my_dict = {k:i for k, i in keypaths(sample)}

这假定您的所有值都是唯一的,否则路径会被覆盖。

或者,您也可以在不修改 keypaths 函数的情况下执行相同操作(如果需要用于其他目的):

def keypaths(myDict):    
        for key, value in myDict.items():
            if isinstance(value, collections.Mapping):
                for subkey, subvalue in keypaths(value):
                    yield [key] + subkey, subvalue
            else:
                yield [key], value

    my_dict = {i: keypath for keypath, value in keypaths(sample) for i in value}

请注意,此替代方法仅在您的所有值都是 lists 时才有效(否则字典理解将失败)。

输出:

{'a1': ['PROJ1', 'LOB1'],
 'a2': ['PROJ1', 'LOB1'],
 'aa1': ['PROJ12', 'LOBa'],
 'aa2': ['PROJ12', 'LOBa'],
 'b1': ['PROJ1', 'LOB'],
 'b2': ['PROJ1', 'LOB'],
 'n1': ['PROJ1', 'LOBX'],
 'n2': ['PROJ1', 'LOBX'],
 'o1': ['PROJ1', 'LOBA'],
 'o2': ['PROJ1', 'LOBA'],
 'o3': ['PROJ1', 'LOBA'],
 'oa': ['PROJ1', 'LOBA'],
 'v1': ['PROJ1', 'LOb2'],
 'v2': ['PROJ1', 'LOb2'],
 'vx1': ['PROJ12', 'LOBX'],
 'vx2': ['PROJ12', 'LOBX']}

请注意,这仅适用于假设您的所有值都是 lists(否则字典理解将失败)并且具有唯一值(否则键路径会因重复值而被覆盖)。

现在,要获得keypath,您所要做的就是:

my_dict.get('a1')
# ['PROJ1', 'LOB1']

my_dict.get('o1')
# ['PROJ1', 'LOBA']

my_dict.get('not exist')
# None

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 2011-01-11
    • 2011-07-31
    • 2014-06-06
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多