Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从键列表中获取JSON对象_Python_Json_Dictionary - Fatal编程技术网

Python 从键列表中获取JSON对象

Python 从键列表中获取JSON对象,python,json,dictionary,Python,Json,Dictionary,我有一个动态构建的字典,它可能看起来像这样: my_dict = {"ministry": { "of": { "silly": { "walks": {} } } }, "foo": "bar", "spam": { "ministry": { "of": "silly"

我有一个动态构建的字典,它可能看起来像这样:

my_dict = {"ministry": {
         "of": {
             "silly": {
                 "walks": {}
                 }
             }
          },
    "foo": "bar",
    "spam": {
        "ministry": {
            "of": "silly"
            }
        }
    }
my_keys = ["ministry", "of", "silly", "walks"]
my_found_item = get(my_dict, my_keys)
if my_found_item:
    my_found_item["new"] = "entry"

print(my_dict)
my_keys = ["ministry", "of", "silly"]
然后我有一个键列表,它是我想要找到的对象的地址,如下所示:

my_dict = {"ministry": {
         "of": {
             "silly": {
                 "walks": {}
                 }
             }
          },
    "foo": "bar",
    "spam": {
        "ministry": {
            "of": "silly"
            }
        }
    }
my_keys = ["ministry", "of", "silly", "walks"]
my_found_item = get(my_dict, my_keys)
if my_found_item:
    my_found_item["new"] = "entry"

print(my_dict)
my_keys = ["ministry", "of", "silly"]
使用my_键到达my_dict中的位置的最佳方式是什么。在那里,我还想添加一个新条目

我想了好几天,在谷歌上搜索了好几天,但没有发现任何东西,我唯一能想到的就是把它重新制作成一个XML对象

我想做一些像

my_dict[my_keys[0]][my_keys[1]][my_keys[2]][my_keys[3]] = {"new":"entry"}
但我从来不知道我的钥匙列表中有多少项。你们怎么解决这个问题


编辑1: 根据我的回答,我这样做了

def get(json_object, path):
    if type(path) == str:
        path = path.split(".")

    if type(path) != list or len(path) == 0:
        return

    key = path.pop(0)

    if len(path) == 0:
        try:
            return json_object[key]
        except KeyError:
            return

    if len(path):
        return get(json_object[key], path)
然后使用如下方式:

my_dict = {"ministry": {
         "of": {
             "silly": {
                 "walks": {}
                 }
             }
          },
    "foo": "bar",
    "spam": {
        "ministry": {
            "of": "silly"
            }
        }
    }
my_keys = ["ministry", "of", "silly", "walks"]
my_found_item = get(my_dict, my_keys)
if my_found_item:
    my_found_item["new"] = "entry"

print(my_dict)
my_keys = ["ministry", "of", "silly"]
如果我的_键如下所示,则该选项有效:

my_dict = {"ministry": {
         "of": {
             "silly": {
                 "walks": {}
                 }
             }
          },
    "foo": "bar",
    "spam": {
        "ministry": {
            "of": "silly"
            }
        }
    }
my_keys = ["ministry", "of", "silly", "walks"]
my_found_item = get(my_dict, my_keys)
if my_found_item:
    my_found_item["new"] = "entry"

print(my_dict)
my_keys = ["ministry", "of", "silly"]
但是如果我的钥匙像这样一直掉下去,它就不会工作了

my_keys = ["ministry", "of", "silly", "walks"]

my_found_item = get(my_dict, my_keys)
if my_found_item:
    my_found_item["new"] = "entry"
有人知道如何解决这个“小”问题吗


编辑2 当然,这是因为我需要检查我的\u found\u项目是否为none。此更改修复了它:

if my_found_item is not None:
    my_found_item["new"] = "entry"

用答案回答了我自己的问题

如果您信任输入,则可以从键构建字符串并使用exec:

my_dict = {"ministry": {
         "of": {
             "silly": {
                 "walks": {}
                 }
             }
          },
    "foo": "bar",
    "spam": {
        "ministry": {
            "of": "silly"
            }
        }
    }

my_keys = ["ministry", "of", "silly", "walks"]


exec """my_dict{} = {{"new":"entry"}}""".format("".join(map("['{}']".format, my_keys)))
演示:

如果还希望检索该值,请执行以下操作:

def pairing(d, new,keylist):
    path = "".join(map("['{}']".format, keylist))
    exec "get_val = d{}".format(path)
    exec "d{path} = {new}".format(new=new,path=path)
    return get_val
演示:

如果您传递了错误的密钥,您将得到一个密钥错误,通常情况下:

n [61]: my_keys = ["ministry", "of", "silly", "foo"]

In [62]: pairing(my_dict, {"new":"pairing"}, my_keys)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
...................
<string> in <module>()

KeyError: 'foo'
n[61]:我的钥匙=[“部”、“的”、“傻的”、“福”]
在[62]中:配对(my_dict,{“new”:“配对”},my_键)
---------------------------------------------------------------------------
KeyError回溯(最近一次呼叫最后一次)
...................
在()
KeyError:“foo”
如果需要,您可以像通常一样使用
try/except
dict.get
捕捉任何错误。

使用递归

您想要的函数已在名为的Javascript库中编写。现在您不能简单地将JS复制并粘贴到python中,您需要进行一些翻译。这里要注意的是技术

特别是他们编写了一个
.get()
函数,该函数将在对象的深处查找由包含点的字符串定义的路径,如
ministry.of.silly.walks

实现源代码是:

var get=module.exports.get=函数get(对象,路径){ 如果(路径类型==“字符串”){ 路径=路径分割(“.”); } if(!(数组的路径实例)| | path.length==0){ 返回; } path=path.slice(); var key=path.shift(); if(对象类型!==“对象”| |对象===null){ 返回; } if(path.length==0){ 返回对象[键]; } if(路径长度){ 返回get(对象[键],路径); } };
  • 该函数用于将字符串或数组作为参数(
    path
    ),并确定它是哪个
  • 描述字符串
    ministry.of.silly.walks
    上拆分,以获得存储在path中的数组(即path现在设置为
    ['ministry'、'of'、'silly'、'walks']
  • 使用
    path.shift()
    删除
    path
    的第一个元素,并将其放入
    key
    ,用于访问对象的一个级别(
    object[key]
  • 如果描述符超出级别(
    path.length==0
    ),我们就完成并找到了元素(
    object[key]
    )。如果没有,我们将简化级别的对象(
    object[key]
    )和路径数组的剩余部分递归地传递回get(
    return get(object[key],path)
  • 这个递归方法应该适用于任何语言。我想你会发现python有
    .shift()
    ,对于
    .slice()
    ,你想在python中替换一个复制操作,它可以是
    path=path[:]
    path=copy.copy(path)
    。如果要在找到对象中的正确位置后添加新条目,则需要为其添加参数,并将其复制到递归调用中。

    基于Javascript dotty的答案

    my_dict = {"ministry": {
             "of": {
                 "silly": {
                     "walks": {}
                     }
                 }
              },
        "foo": "bar",
        "spam": {
            "ministry": {
                "of": "silly"
                }
            }
        }
    
    my_keys = ["ministry", "of", "silly"]
    
    
    def get_json(json_object, path):
        __path = path[:]
        if type(__path) == str:
            __path = __path.split(".")
    
        if type(path) != list or len(__path) == 0:
            return
    
        key = __path.pop(0)
    
        if len(__path) == 0:
            try:
                return json_object[key]
            except KeyError:
                return
    
        if len(__path):
            return get_json(json_object[key], __path)
    
        my_found_item = get(my_dict, my_keys)
        if my_found_item is not None:
            my_found_item["new"] = "entry"
    
        print(my_dict)
    
    可以使用访问字典中的元素

    from jsonpointer import resolve_pointer
    
    my_pointer = '/' + '/'.join(my_keys)
    
    resolve_pointer(my_dict, my_pointer)['new'] = 'entry'
    
    编辑:
    我刚刚发现,它看起来比jsonpointer更强大,你所说的“在我的字典中找到位置。在那里我还想添加一个新条目”是什么意思?只要继续,直到我的字典结束_keys@AlekhyaVemavarapu我在最后一段代码中展示的:)第二条if语句中是否缺少缩进?看起来它应该只在路径被分割时运行,如果分割不正确则终止。@Paul我不这么认为。除了一种情况外,它工作正常。我会用它更新我原来的帖子。