无法从已解析的字典中返回“有效”字段

时间:2019-07-30 12:00:12

标签: python json

我使用以下格式的json:

myDict =
{
  "Garden": {
    "GroundFloor": {
      "@loc": "porch",
      "@myID": "35C",
      "Tid": "1",
      "InfoList": {
        "status": {
          "@default": "0",
          "@myID": "20C"
        },
        "count": {
          "@default": "0",
          "@myID": "1"
        }
      }
    },
      "TopFloor": {
      "@loc": "backyard",
      "@myID": "35C",
      "Tid": "2",
      "InfoList": {
        "status": {
          "@default": "0",
          "@myID": "20D"
        },
        "count": {
          "@default": "0",
          "@myID": "2"
        }
      }
    }
  },
"BackYard": {
    "GroundFloor": {
      "@loc": "porch",
      "@myID": "35C",
      "Tid": "3",
      "InfoList": {
        "status": {
          "@default": "0",
          "@myID": "20C"
        },
        "count": {
          "@default": "0",
          "@myID": "1"
        }
      }
    },
      "TopFloor": {
      "@loc": "backyard",
      "@myID": "35C",
      "Tid": "4",
      "InfoList": {
        "status": {
          "@default": "0",
          "@myID": "20D"
        },
        "count": {
          "@default": "0",
          "@myID": "2"
        }
      }
    }
  },
... many more nested layers...
}

我将其存储到字典中,并且需要对此进行一些处理。

对于给定的“ Tid”,我希望能够在“状态”部分返回“ @default”值。例如,如果我请求“ Tid” = 1,我应该得到以下输出。

预期输出:

{ "Tid": "1",
  "status": "0"  -->this is the value from the @default attribute
} 
# note that the "status" value is the attribute @default.

到目前为止,我有以下方法,但是它返回了这个信息,我不明白为什么。

{ "Tid": null,
  "status": null
} 

我的方法:

def get_system_state(myDict, id):
    for i in  ["id", "@default"]:
        print (myDict.get(i))
    if any(c == id_type for c in myDict.values()):
        yield {i: myDict.get(i) for i in ["id", "@default"]}
    else:
        for i in myDict.values():
            if isinstance(i, dict):
                yield from get_system_state(i, id_type)

# Called by
get_system_state(myDict, 1)

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

为了测试目的,我只是更改了字典"Tid": "2","InfoList": { "status": { "@default": "1","@myID": "20D"}, @default值。

  • isdigit()方法如果字符串中的所有字符都是数字,则返回“ True”,否则,返回“ False”。

例如。

myDict ={
  "Garden": {
    "GroundFloor": {
      "@loc": "porch",
      "@myID": "35C",
      "Tid": "1",
      "InfoList": {"status": { "@default": "0","@myID": "20C"},
      "count": {"@default": "0","@myID": "1"}
      }
    },
      "TopFloor": {
      "@loc": "backyard",
      "@myID": "35C",
      "Tid": "2",
      "InfoList": { "status": { "@default": "1","@myID": "20D"},
      "count": {"@default": "0","@myID": "2" }
      }
    }
  }
}


def get_system_state(myDict, id):
    for k,v in myDict['Garden'].items():
        for x in v:
            if 'Tid' in v and v['Tid'] is not None and v['Tid'].isdigit() and int(v['Tid']) == id:
                return [{'Tid':id,'status':v['InfoList']['status']['@default']}]

new_dict = get_system_state(myDict, 1)
print(new_dict)

O / P:

[{'Tid': 1, 'status': '0'}]

如果您通过id=2

new_dict = get_system_state(myDict, 2)

O / P:

[{'Tid': 2, 'status': '1'}]

更新

如果词典没有“花园”作为顶级词典

def get_system_state(myDict, id):
    for k1,v1 in myDict.items():
        for k,v in v1.items():
            for x in v:
                if 'Tid' in v and v['Tid'] is not None and v['Tid'].isdigit() and int(v['Tid']) == id:
                    return [{'Tid':id,'status':v['InfoList']['status']['@default']}]

答案 1 :(得分:1)

您可以使用简单的递归:

data = {'Garden': {'GroundFloor': {'@loc': 'porch', '@myID': '35C', 'Tid': '1', 'InfoList': {'status': {'@default': '0', '@myID': '20C'}, 'count': {'@default': '0', '@myID': '1'}}}, 'TopFloor': {'@loc': 'backyard', '@myID': '35C', 'Tid': '2', 'InfoList': {'status': {'@default': '0', '@myID': '20D'}, 'count': {'@default': '0', '@myID': '2'}}}}, 'BackYard': {'GroundFloor': {'@loc': 'porch', '@myID': '35C', 'Tid': '3', 'InfoList': {'status': {'@default': '0', '@myID': '20C'}, 'count': {'@default': '0', '@myID': '1'}}}, 'TopFloor': {'@loc': 'backyard', '@myID': '35C', 'Tid': '4', 'InfoList': {'status': {'@default': '0', '@myID': '20D'}, 'count': {'@default': '0', '@myID': '2'}}}}}
def get_id(d, id):
   if isinstance(d, dict) and d.get('Tid') == id:
      yield {'Tid':d['Tid'], 'status':d['InfoList']['status']['@default']}
   for i in getattr(d, 'values', lambda :[])():
      yield from get_id(i, id)

print(list(get_id(data, '1')))

输出:

[{'Tid': '1', 'status': '0'}]

答案 2 :(得分:0)

尝试使用此:

def get_system_state(myDict, id):
    garden_details = myDict.get("Garden", None)
    if garden_details:
        for floor in garden_details:
            Tid = garden_details[floor].get(str("Tid"), None)
            if Tid == str(id):
                return {'Tid': Tid, 'status': garden_details[floor]['InfoList']['status']['@default']}

检查是否适合您。