Python-脚本从JSON中读取一个值,并在CSV中写入200次
我正在编写一个Python脚本,它从多个JSON文件中读取数据,并将其写入单个输出CSV文件。我写了一些代码,但不正确。为了简单起见,我在这里格式化了JSON,否则它只在一行上。每个“请求id”包含多个“id”值。我当前的代码只能读取一个“id”,并重复200次。不知道为什么会这样 JSON文件Python-脚本从JSON中读取一个值,并在CSV中写入200次,python,json,Python,Json,我正在编写一个Python脚本,它从多个JSON文件中读取数据,并将其写入单个输出CSV文件。我写了一些代码,但不正确。为了简单起见,我在这里格式化了JSON,否则它只在一行上。每个“请求id”包含多个“id”值。我当前的代码只能读取一个“id”,并重复200次。不知道为什么会这样 JSON文件 Python代码 看看这里: my_dict_list =[] try: for f in os.listdir(file_dir): if f.endswith('.json
Python代码 看看这里:
my_dict_list =[]
try:
for f in os.listdir(file_dir):
if f.endswith('.json') and f.startswith('emails_'):
file_path = os.path.join(file_dir, f)
data = open(file_path, 'r')
for line in data:
my_dict = {}
parsed_data = json.loads(line)
# ...
for result in parsed_data["result"]:
# ...
my_dict_list.append(my_dict)
my_dict
是一本仅在文件行级别更新的词典。但是您想要做的似乎是在解析的_数据[“result”]
的每个元素上。如果将同一个dict附加到循环中的一个列表中并对其进行变异,实际上就是将多个相同的副本放入该列表中,而当进行变异时,则会对所有副本进行变异。(“复制”在Python中是一个不好的术语,因为它们实际上只是引用)
若要解决此问题,请尝试替换此:
my_dict_list.append(my_dict)
为此:
my_dict_list.append(dict(my_dict))
这将在放入列表之前创建一个(浅)副本。这是Python中常见的一个问题。这里重要的是,我的dict是指向dict的指针 这里发生的事情是,您正在定义my_dict(指向dict的指针),用一组值更新它,然后将其附加到列表中。然后在循环的第二次迭代中,更改my_dict的值,并将其附加到数组中的第二个位置。但是,my_dict也位于数组的第一个位置。所以my_dict的值现在在数组的索引0和索引1中都被更新 因此,列表中的每个dict中的所有值都会更新,而不仅仅是Id。这将持续到循环的最后一次迭代,此时列表中的所有条目(它们都是my_dict)都会更新为结果中最后一个dict的值 解决这个问题的一种方法是在每次迭代中定义一个新的dict
for line in data:
parsed_data = json.loads(line)
for result in parsed_data["result"]:
my_dict = {}
my_dict["REQUEST_ID"] = parsed_data["requestId"]
my_dict["SUCCESS"] = parsed_data["success"]
my_dict["RESULT_ID"] = result["id"]
my_dict["NAME"] = result["name"]
my_dict["DESCRIPTION"] = result.get("description")
my_dict["STATUS"] = result["status"].encode('utf-8')
my_dict["FOLDER_TYPE"] = result["folder"]["type"]
my_dict["FOLDER_ID"] = result["folder"]["value"]
my_dict["FOLDER_NAME"] = result["folder"]["folderName"]
my_dict["FROM_EMAIL_TYPE"] = result["fromEmail"]["type"]
my_dict["FROM_EMAIL_VALUE"] = result["fromEmail"]["value"]
my_dict["FROM_NAME_TYPE"] = result["fromName"]["type"]
my_dict["FROM_NAME_VALUE"] = result["fromName"]["value"]
my_dict["REPLY_EMAIL_TYPE"] = result["replyEmail"]["type"]
my_dict["REPLY_EMAIL_VALUE"] = result["replyEmail"]["value"]
my_dict["SUBJECT_TYPE"] = result["subject"]["type"]
my_dict["SUBJECT_VALUE"] = result["subject"]["value"]
my_dict["OPERATIONAL"] = result["operational"]
my_dict["PUBLISH_TO_MSI"] = result["publishToMSI"]
my_dict["TEMPLATE"] = result["template"]
my_dict["TEXT_ONLY"] = result["textOnly"]
my_dict["URL"] = result.get("url")
my_dict["WEBVIEW"] = result["webView"]
my_dict["CREATED_AT"] = result["createdAt"]
my_dict["UPDATED_AT"] = result["updatedAt"]
my_dict["WORKSPACE"] = result["workspace"]
my_dict_list.append(my_dict)
既然每个文件已经有一行,为什么要从文件中读取行?
本部分:
data = open(file_path, 'r')
for line in data:
my_dict = {}
parsed_data = json.loads(line)
可简化为:
my_dict = {}
parsed_data = json.loads(open(file_path, 'r').read())
谢谢@amanbirs。你的解释有道理,解决了问题。创建一个新列表(你的方法)和Adrian Tam在下面发布的内容有什么区别。在我的示例中,我在结果循环的开头定义了一个新字典。Adrian使用的是同一本词典,但在添加到列表时会进行复制,从而在列表中的不同索引处插入不同的词典。这两个都是有效的,只是风格而已。再次感谢@amanbirs。我正在考虑在这个特定的块中添加异常处理。如果数据中出现任何错误,我想将我的_dict[“REQUEST_ID”]和我的_dict[“RESULT_ID”]值写入日志文件。类似这样但不确定是否准确:
除了ValueError:logger=logging.getLogger(\uuuu name\uuuuu)logger.info(“请求ID{my_dict['Request_ID']}和结果ID{my_dict['SUCCESS']}),exc_info=True)
@django uncheed不确定我是否理解这个问题。也许你可以把它做成一个新的帖子,这样你就可以清楚地解释它,其他人也可以提出答案?这里是:[
data = open(file_path, 'r')
for line in data:
my_dict = {}
parsed_data = json.loads(line)
my_dict = {}
parsed_data = json.loads(open(file_path, 'r').read())