Python 根据键值将路由存储到“@myID”
我有一个json,格式如下Python 根据键值将路由存储到“@myID”,python,json,parsing,Python,Json,Parsing,我有一个json,格式如下 json_tree ={ "Garden": { "Seaside": { "@loc": "127.0.0.1", "@myID": "1.3.1", "Shoreside": { "@myID": "3", "InfoList": { "Notes": { "@code": "0", "@myID": "1"
json_tree ={
"Garden": {
"Seaside": {
"@loc": "127.0.0.1",
"@myID": "1.3.1",
"Shoreside": {
"@myID": "3",
"InfoList": {
"Notes": {
"@code": "0",
"@myID": "1"
},
"Count": {
"@myID": "2",
"@val": "0"
}
},
"state": "0",
"Tid": "3",
"Lakesshore": {
"@myID": "4",
"InfoList": {
"Notes": {
"@code": "0",
"@oid": "1"
},
"Count": {
"@myID": "2",
"@val": "0"
}
},
"state": "0",
"Tid": "4"
}
},
"state": "0",
"Tid": "2"
},
"Tid": "1",
"state": "0"
}
}
我的实施:
def getmyID(json_tree, itemList):
for k1, v1 in json_tree .items():
for k,v in v1.items():
if k == itemList:
return '{}{}.{}'.format(json_tree['@myID'] + '.' if '@myID' in json_tree else '',
v['@myID'], v['InfoList']['status']['@myID'])
我遇到的问题是,当我想找到通往后院的路线时,这个方法不起作用,因为它返回None。请注意,“后院”嵌套在Seaside节点中
我正在将密钥节点的@myID附加到相应状态节点中的@myID
getmyID(json_tree, "Seaside")
"Output" = "1.2.3.26" --> Currently I get this only
getmyID(json_tree, "BackYard")
"Output" = "1.2.3.75.32" --> expected output but getting "None"
任何帮助都将不胜感激。
谢谢。编辑-我不介意人们否决我的答案,甚至编辑它们,只要他们告诉我为什么。希望能收到伊维特·科伦布和克里斯芙的回音 下面是我使用基于堆栈的方法提出的解决方案。其思想是,在找到所需的键(称为itemList)之前,要尽量深入嵌套结构。我相信一定有更可爱的方式:
json_tree = {
"Gardens": {
"Seaside": {
"@loc": "porch",
"@myID": "1.2.3",
"Tid": "1",
"InfoList": {
"status": {
"@default": "0",
"@myID": "26"
},
"count": {
"@default": "0",
"@myID": "1"
}
},
"BackYard": {
"@myID": "75",
"Tid": "2",
"InfoList": {
"status": {
"@default": "6",
"@myID": "32"
},
"count": {
"@default": "0",
"@myID": "2"
}
}
}
}
}
}
def is_valid_kv_pair(key, value):
try:
assert isinstance(key, str)
assert isinstance(value, dict)
assert isinstance(value["@myID"], str)
assert isinstance(value["Tid"], str)
assert isinstance(value["InfoList"], dict)
assert isinstance(value["InfoList"]["status"], dict)
assert isinstance(value["InfoList"]["status"]["@default"], str)
assert isinstance(value["InfoList"]["status"]["@myID"], str)
except (AssertionError, KeyError):
return False
else:
return True
def get_id(dictionary, desired_key):
if not isinstance(dictionary, dict):
return None
dictionary_stack = [dictionary]
root_stack = []
while dictionary_stack:
current_dictionary = dictionary_stack.pop()
appended_root = False
for key, value in current_dictionary.items():
if appended_root:
root_stack.pop()
if is_valid_kv_pair(key, value):
if key == desired_key:
rootIDs = [d["@myID"] for d in root_stack]
myID = value["@myID"]
statusID = value["InfoList"]["status"]["@myID"]
return ".".join(rootIDs + [myID] + [statusID])
root_stack.append(value)
appended_root = True
if isinstance(value, dict):
dictionary_stack.append(value)
return None
ID = get_id(json_tree, "BackYard")
print(ID)
可以对生成器使用递归:
def get_vals(d, target, path = []):
for a, b in d.items():
if a == target:
yield '.'.join(filter(None, path+[b['@myID'], b["InfoList"]['status']['@myID']]))
if isinstance(b, dict):
yield from get_vals(b, target, path + [b.get('@myID', '')])
print(list(get_vals(json_tree, "Seaside")))
print(list(get_vals(json_tree, "BackYard")))
输出:
['1.2.3.26']
['1.2.3.75.32']
['1.3.1']
['1.3.1.3.1']
编辑:最新数据:
def get_vals(d, target, paths = []):
for a, b in d.items():
if a == target:
yield '.'.join(filter(None, paths+[b["@myID"], b.get("InfoList", {}).get('Notes', {}).get('@myID')]))
if isinstance(b, dict):
yield from get_vals(b, target, paths+[b.get('@myID')])
print(list(get_vals(json_tree, "Seaside")))
print(list(get_vals(json_tree, 'Shoreside')))
输出:
['1.2.3.26']
['1.2.3.75.32']
['1.3.1']
['1.3.1.3.1']
您的输入树不包含@oid key,您将无法获得预期的结果output@RomanPerekhrest更新了代码。这是我的一个输入错误。d['@myID']中的d是什么?@glibdud它实际上是json_树,它是一个输入错误。抱歉,json_字典应该是json_树吗?作为将来的参考,如果您在将代码复制到帖子中时更改了代码,最好将其复制回来,并确保在发布之前按预期运行。我认为我的代码存在问题,我希望具有上述预期行为。我无法找出错误在我的函数中的位置。后院坐落在海边。你能详细解释一下为什么后院的预期产量是1.2.75.23吗?这些数字应该从哪里来?我明白了,所以后院的预期产量应该是1.2.3.75.32,而不是1.2.75.23。我会修改一下我的答案。是的!!确切地说,我更新了代码注释以反映更改。这是我的错别字。对不起:哦,我明白了。当你指根节点时,你指的不是直接的父节点,而是第一个节点?换句话说,由于C嵌套在B中,C的ID不会是4.5.6.7.8.9.128?它就像一个符咒再次感谢你@劳拉史密斯很乐意帮忙@劳拉斯密斯:谢谢你的澄清:去海边怎么样?是您在Seaside下组合所有@myID键值或任何输入键的逻辑。@LauraSmith很抱歉延迟响应,请查看我最近的编辑。@LauraSmith很乐意提供帮助!