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)
).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我不这么认为。除了一种情况外,它工作正常。我会用它更新我原来的帖子。