来自键路径的嵌套字典值

min*_*bro 13 python dictionary

借助键路径从嵌套字典中获取值,这里是dict:

json = {
    "app": {
        "Garden": {
            "Flowers": {
                "Red flower": "Rose",
                "White Flower": "Jasmine",
                "Yellow Flower": "Marigold"
            }
        },
        "Fruits": {
            "Yellow fruit": "Mango",
            "Green fruit": "Guava",
            "White Flower": "groovy"
        },
        "Trees": {
            "label": {
                "Yellow fruit": "Pumpkin",
                "White Flower": "Bogan"
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

该方法的输入参数是以点分隔的键路径,从键路径="app.Garden.Flowers.white Flower"需要打印'Jasmine'.我的代码到目前为止:

import json
with open('data.json') as data_file:    
  j = json.load(data_file)


def find(element, JSON):     
  paths = element.split(".")  
  # print JSON[paths[0]][paths[1]][paths[2]][paths[3]]
  for i in range(0,len(paths)):
    data = JSON[paths[i]]
    # data = data[paths[i+1]]
    print data



find('app.Garden.Flowers.White Flower',j)
Run Code Online (Sandbox Code Playgroud)

Cea*_*sta 28

这是折叠的一个例子.你可以这样简洁地写出来:

import operator

def find(element, json):
    return reduce(operator.getitem, element.split('.'), json)
Run Code Online (Sandbox Code Playgroud)

或者更多的Python(因为reduce()可读性差而不赞成),如下所示:

def find(element, json):
    keys = element.split('.')
    rv = json
    for key in keys:
        rv = rv[key]
    return rv

j = {"app": {
    "Garden": {
        "Flowers": {
            "Red flower": "Rose",
            "White Flower": "Jasmine",
            "Yellow Flower": "Marigold"
        }
    },
    "Fruits": {
        "Yellow fruit": "Mango",
        "Green fruit": "Guava",
        "White Flower": "groovy"
    },
    "Trees": {
        "label": {
            "Yellow fruit": "Pumpkin",
            "White Flower": "Bogan"
        }
    }
}}
print find('app.Garden.Flowers.White Flower', j)
Run Code Online (Sandbox Code Playgroud)

  • 如果你想通过整数索引(app.Garden.Flowers.0)来寻址一个项目,你可以像这样改变你的for循环:尝试:rv = rv[int(key)] except:rv = rv[key] – nr 4 分钟前 编辑 (2认同)

Fab*_*amo 7

我建议您使用python-benedict,一个具有完整键路径支持和许多实用方法的 python dict 子类。

你只需要转换你现有的字典:

d = benedict(json)
# now your keys support dotted keypaths
print(d['app.Garden.Flower.White Flower'])
Run Code Online (Sandbox Code Playgroud)

这里是库和文档: https: //github.com/fabiocaccamo/python-benedict

注:我是该项目的作者


jua*_*nra 6

参加聚会有点晚,但是我也遇到了类似的情况,并找到了这个dpath模块。好,易于。

希望这对其他人有帮助:)


Mas*_*din 1

很接近。您需要(正如您在评论中所说的那样)递归地遍历主要 JSON 对象。您可以通过存储最外面的键/值的结果,然后使用它来获取下一个键/值等来实现这一点,直到您没有路径为止。

def find(element, JSON):     
  paths = element.split(".")
  data = JSON
  for i in range(0,len(paths)):
    data = data[paths[i]]
  print data
Run Code Online (Sandbox Code Playgroud)

不过,您仍然需要注意 KeyErrors。