python - 如何在python中附加一个列表时处理异常,其中包含从存储从.json文件读取的数据的dict读取的数据?

Posted

技术标签:

【中文标题】python - 如何在python中附加一个列表时处理异常,其中包含从存储从.json文件读取的数据的dict读取的数据?【英文标题】:How to handle exceptions while appending a list in python with data read from a dict that stores data read from a .json file? 【发布时间】:2018-06-17 01:15:45 【问题描述】:

我是 Python 新手,遇到了一个非常具体的问题。我需要从具有相似结构的各种 JSON 文件中读取数据。过程是:将 JSON 文件加载到字典中,将字典中的相关数据保存在列表中,以便将其插入 mysql 数据库。问题是:JSON 文件的某些字段不一定出现在每个 JSON 文件中。某些文件中缺少某些字段,有时甚至在同一个文件中,例如:

  "actions": [
    
      "acted_at": "2014-12-10", 
      "action_code": "Intro-H", 
      "references": [], 
      "text": "Introduced in House", 
      "type": "action"
    , 
    
      "acted_at": "2014-12-10", 
      "action_code": "H11100", 
      "committees": [
        "HSWM"
      ], 
      "references": [], 
      "status": "REFERRED", 
      "text": "Referred to the House Committee on Ways and Means.", 
      "type": "referral"
    , 
    
      "acted_at": "2014-12-12", 
      "action_code": "B00100", 
      "references": [
        
          "reference": "CR E1800-1801", 
          "type": null
        
      ], 
      "text": "Sponsor introductory remarks on measure.", 
      "type": "action"
    
  ]

这是一个代码 sn-p 来说明我的程序的相关(与问题)部分的作用:

hr_list = []
with open("data.json") as json_data:
    d = json.load(json_data)
    actions_list.append((
    d["actions"][j]["acted_at"],
    d["actions"][j]["action_code"],
    d["actions"][j]["status"],
    d["actions"][j]["text"],
    d["actions"][j]["type"]))

如您所见,文件有一定的一致性。问题是:每当其中一个字段不存在时,我都会收到KeyError,说明没有此类数据可附加到列表中。我需要做的是处理这个异常的方法,比如添加某种类型的“null”数据作为默认值,所以它不会返回任何错误(当添加到数据库时无论如何都会是 null)。

【问题讨论】:

【参考方案1】:

您可以使用dict.get() 指定默认值,例如:

with open("data.json") as json_data:
    d = json.load(json_data)
    actions_list.append((
        d["actions"][j].get("acted_at", ''),
        d["actions"][j].get("action_code", ''),
        d["actions"][j].get("status", ''),
        d["actions"][j].get("text", ''),
        d["actions"][j].get("type", '')
    ))

【讨论】:

【参考方案2】:

首先,我将代码移出with 块。

actions_list = []
with open("data.json") as json_data:
    d = json.load(json_data)

actions_list.append((
d["actions"][j]["acted_at"],
d["actions"][j]["action_code"],
d["actions"][j]["status"],
d["actions"][j]["text"],
d["actions"][j]["type"]))

其次,如果我必须按照您的要求做,我会使用一个函数来可选地获取值/返回 None。

actions_list = []
with open("data.json") as json_data:
    d = json.load(json_data)

def f(d, j, k):
    try:
        return d["actions"][j][k] 
    except:
        return None

actions_list.append((
f(j, "acted_at"),
f(j, "action_code"),
f(j, "status"),
f(j, "text")))

或者,您可以检查所有数据的键,作为验证步骤,然后检索值。

此外,您可以在dict 上使用get 函数来获取valuevalue(如果存在),如果不存在则返回一些默认值。

d.get(k, "default_return_value")

如果你想安全返回None只是为了最深的窝,你可以这样做

d["actions"][j].get("acted_at", None)

【讨论】:

我真的很喜欢“d.get”方法。我正在处理数千个文件。我测试了您描述的所有解决方案并最终使用了 d.get 一个。但我想知道:您知道在您列出的方法中哪种方法最快吗? 我假设d.get 会比使用try: ... except: ... 块更快。我必须使用示例程序/使用dis 进行检查以确保。我最初的假设是直接字典访问比使用比引发异常更快的函数更快。【参考方案3】:

你自己提到了。使用 try-catch 逻辑,您可以在不中断程序执行的情况下捕获特定错误并处理它们,从而填充空数据点。

因此,使用您的 sn-p,用 try 包围 append 方法,然后添加 except。这是有关 try-catch 逻辑的 python 文档。 https://docs.python.org/3/tutorial/errors.html#handling-exceptions

hr_list = []
with open("data.json") as json_data:
    d = json.load(json_data)
    dict_keys = ["acted_at","action_code","status","text","type"]
    for d_key in dict_keys:
        try:
            actions_list.append(d["actions"][j][d_key])
        except KeyError as e:
            cause = e.args[0]
            actions_list.append((d["actions"][j][cause] = NULL))

您提到的异常 keyerror 记录在 here。然后对于KeyError,第一个参数是引发异常的键。这样,您就可以将违规密钥存储在 cause 中。

这样,缺失的值应该被填充。

【讨论】:

如果这对你有帮助,请接受这个答案。否则让我知道出了什么问题。 您的解决方案确实解决了我的问题,但我最终使用了 d.get 方法,因为我认为它更简单、更干净。

以上是关于python - 如何在python中附加一个列表时处理异常,其中包含从存储从.json文件读取的数据的dict读取的数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在并行进程(python)中将项目附加到列表中?

python - 如何在python中附加一个列表时处理异常,其中包含从存储从.json文件读取的数据的dict读取的数据?

在 Python 中将多个变量附加到列表中

从文本文件中读取句子并使用 Python 3 附加到列表中 [关闭]

如何在python中附加到列表时格式化字符串和小数

Python - 如何创建一个空的numpy数组并附加到它,如列表[重复]