Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.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 根据键值将路由存储到“@myID”_Python_Json_Parsing - Fatal编程技术网

Python 根据键值将路由存储到“@myID”

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,格式如下

 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很乐意提供帮助!