Поиск, существует ли путь в json в python

#python #json

Вопрос:

Поэтому в настоящее время я пытаюсь работать с api, который возвращает данные json, такие как:

  {
    "emp1" : {
      "EmpName" : "Chris Jackman",
      "EmpAge" : "34",
      "EmpGender" : "Male",
      "EmpDept" : "IT",
      "EmpDesg" : "Project Manager"
      "EmpSal": {
                  "2019": 20000
                  "2020": 23000
 },

    "emp2" : {
      "EmpName" : "Mary Jane",
      "EmpAge" : "27",
      "EmpGender" : "Female",
      "EmpDept" : "IT"
  }
}
 

Иногда, когда мы запрашиваем API, одно из этих полей будет отсутствовать. Когда мы пытаемся получить к нему доступ

 my_var = my_json["emp2"]["EmpDesg"]
 

Который вернет ключевую ошибку:

 data_dict["EmpDesg"] = my_json["emp2"]["EmpDesg"]
KeyError: 'EmpDesg'
 

Есть ли способ аккуратно справиться с отсутствующими путями json, а не оборачивать каждое поле в try catch:

     try:
        data_dict["EmpName"] = my_json["emp1"]["EmpName"]
    except KeyError as e:
        data_dict["EmpName"] = ""

    try:
        data_dict["EmpAge"] = my_json["emp1"]["EmpAge"]
    except KeyError as e:
        data_dict["EmpAge"] = ""

    try:
        data_dict["EmpGender"] = my_json["emp1"]["EmpGender"]
    except KeyError as e:
        data_dict["EmpGender"] = ""

    try:
        data_dict["salary"] = my_json["emp1"]["EmpSal"]["2020"]
    except KeyError as e:
        data_dict["salary"] = ""
 

Ответ №1:

Если вы хотите проверить, существует ли ключ , используйте "key" in data , а не try, except KeyError

В противном случае, если все, что вам нужно, — это значение по умолчанию, когда ключ не существует, используйте .get() с параметром по умолчанию

 emp1 = my_json["emp1"]
data_dict = {
  "EmpName": emp1.get("EmpName", '')
  "EmpAge": emp1.get("EmpAge", '')
}
 

Или

 keys = ['EmpName', 'EmpAge']
data_dict = {k: emp1.get(k, '') for k in keys}
 

Ответ №2:

Чтобы проверить, существует ли путь произвольной длины в данном диктанте:

 def path_exists(d, path) -> bool:
    """Return True if path exists in given dict."""
    next = d
    while path:
        k = path.pop(0)
        if k in next:
            next = next[k]
        else:
            return False

    return True
 

Например:

 
In [4]: path_exists(d, ['emp1', 'EmpName'])
Out[4]: True

In [5]: path_exists(d, ['emp1', 'EmpSal', '2019'])
Out[5]: True

In [6]: path_exists(d, ['emp1', 'EmpSal', '2018'])
Out[6]: False
 

Таким образом, вы можете проверить, существует ли путь (только один раз), прежде чем уверенно пройти дикт.