猿问

将 csv 文件转换为 json,浮点值周围没有引号

我有一些需要转换为 json 的 csv 文件。csv 中的一些浮点值是数字字符串(以保持尾随零)。转换为 json 时,所有键和值都用双引号括起来。我需要数字字符串浮点值没有引号,但保留尾随零。


这是输入 csv 文件的示例:


ACCOUNTNAMEDENORM,DELINQUENCYSTATUS,RETIRED,INVOICEDAYOFWEEK,ID,BEANVERSION,ACCOUNTTYPE,ORGANIZATIONTYPEDENORM,HIDDENTACCOUNTCONTAINERID,NEWPOLICYPAYMENTDISTRIBUTABLE,ACCOUNTNUMBER,PAYMENTMETHOD,INVOICEDELIVERYTYPE,DISTRIBUTIONLIMITTYPE,CLOSEDATE,FIRSTTWICEPERMTHINVOICEDOM,HELDFORINVOICESENDING,FEINDENORM,COLLECTING,ACCOUNTNUMBERDENORM,CHARGEHELD,PUBLICID

John Smith,2.0000000000,0.0000000000,5.0000000000,1234567.0000000000,69.0000000000,1.0000000000,,4321987.0000000000,1,000-000-000-00,10012.0000000000,10002.0000000000,3.0000000000,,1.0000000000,0,,0,000-000-000-00,0,bc:1234346

我得到的 json 输出是:


{"ACCOUNTNAMEDENORM":"John Smith","DELINQUENCYSTATUS":"2.0000000000","RETIRED":"0.0000000000","INVOICEDAYOFWEEK":"5.0000000000","ID":"1234567.0000000000","BEANVERSION":"69.0000000000","ACCOUNTTYPE":"1.0000000000","ORGANIZATIONTYPEDENORM":null,"HIDDENTACCOUNTCONTAINERID":"4321987.0000000000","NEWPOLICYPAYMENTDISTRIBUTABLE":"1","ACCOUNTNUMBER":"000-000-000-00","PAYMENTMETHOD":"12345.0000000000","INVOICEDELIVERYTYPE":"98765.0000000000","DISTRIBUTIONLIMITTYPE":"3.0000000000","CLOSEDATE":null,"FIRSTTWICEPERMTHINVOICEDOM":"1.0000000000","HELDFORINVOICESENDING":"0","FEINDENORM":null,"COLLECTING":"0","ACCOUNTNUMBERDENORM":"000-000-000-00","CHARGEHELD":"0","PUBLICID":"xx:1234346"}

这是我正在使用的代码:


import csv

import json


csvfile = open('output2.csv', 'r')

jsonfile = open('output2.json', 'w')


readHeaders = csv.reader(csvfile)

fieldnames = next(readHeaders)


reader = csv.DictReader(csvfile, fieldnames)


for row in reader:

    json.dump(row, jsonfile, separators=(',', ':'))

    jsonfile.write('\n')



慕尼黑8549860
浏览 137回答 3
3回答

DIEA

现在,根据您的评论,我更好地理解您的问题,这是一个完全不同的答案。请注意,它不使用json模块,只是“手动”进行所需的处理。虽然它可能可以使用该模块来完成,但与下面使用的相对简单的逻辑相比,让它以不同的方式格式化默认情况下识别的 Python 数据类型可能相当复杂——我从经验中知道——。花药注释:与您的代码一样,这会将 csv 文件的每一行转换为有效的 JSON 对象,并将每一行写入文件中的单独行。然而,结果文件的内容在技术上不会是有效的 JSON,因为所有这些单独的对象都需要用逗号分隔并括在[ ]括号中(即,从而成为有效的 JSON“数组”对象)。import csvwith open('output2.csv', 'r', newline='') as csvfile, \     open('output2.json', 'w') as jsonfile:    for row in csv.DictReader(csvfile):        newfmt = []        for field, value in row.items():            field = '"{}"'.format(field)            try:                float(value)            except ValueError:                value = 'null' if value == '' else '"{}"'.format(value)            else:                # Avoid changing integer values to float.                try:                    int(value)                except ValueError:                    pass                else:                    value = '"{}"'.format(value)            newfmt.append((field, value))        json_repr = '{' + ','.join(':'.join(pair) for pair in newfmt) + '}'        jsonfile.write(json_repr + '\n')这是写入文件的 JSON:{"ACCOUNTNAMEDENORM":"John Smith","DELINQUENCYSTATUS":2.0000000000,"RETIRED":0.0000000000,"INVOICEDAYOFWEEK":5.0000000000,"ID":1234567.0000000000,"BEANVERSION":69.0000000000,"ACCOUNTTYPE":1.0000000000,"ORGANIZATIONTYPEDENORM":null,"HIDDENTACCOUNTCONTAINERID":4321987.0000000000,"NEWPOLICYPAYMENTDISTRIBUTABLE":"1","ACCOUNTNUMBER":"000-000-000-00","PAYMENTMETHOD":12345.0000000000,"INVOICEDELIVERYTYPE":98765.0000000000,"DISTRIBUTIONLIMITTYPE":3.0000000000,"CLOSEDATE":null,"FIRSTTWICEPERMTHINVOICEDOM":1.0000000000,"HELDFORINVOICESENDING":"0","FEINDENORM":null,"COLLECTING":"0","ACCOUNTNUMBERDENORM":"000-000-000-00","CHARGEHELD":"0","PUBLICID":"bc:1234346"}下面再次显示添加了空格:{"ACCOUNTNAMEDENORM": "John Smith", "DELINQUENCYSTATUS": 2.0000000000, "RETIRED": 0.0000000000, "INVOICEDAYOFWEEK": 5.0000000000, "ID": 1234567.0000000000, "BEANVERSION": 69.0000000000, "ACCOUNTTYPE": 1.0000000000, "ORGANIZATIONTYPEDENORM": null, "HIDDENTACCOUNTCONTAINERID": 4321987.0000000000, "NEWPOLICYPAYMENTDISTRIBUTABLE": "1", "ACCOUNTNUMBER": "000-000-000-00", "PAYMENTMETHOD": 12345.0000000000, "INVOICEDELIVERYTYPE": 98765.0000000000, "DISTRIBUTIONLIMITTYPE": 3.0000000000, "CLOSEDATE": null, "FIRSTTWICEPERMTHINVOICEDOM": 1.0000000000, "HELDFORINVOICESENDING": "0", "FEINDENORM": null, "COLLECTING": "0", "ACCOUNTNUMBERDENORM": "000-000-000-00", "CHARGEHELD": "0", "PUBLICID": "bc:1234346"}

皈依舞

哈,真的很有趣,我想和你找到相反的答案,结果是带引号的。其实很容易自动删除它,只需删除参数“separators=(',',':')”。对我来说,只需添加这个参数就可以了。

梵蒂冈之花

一种解决方案是使用正则表达式查看字符串值是否看起来像浮点数,如果是,则将其转换为浮点数。import renull = Nonej = {"ACCOUNTNAMEDENORM":"John Smith","DELINQUENCYSTATUS":"2.0000000000",     "RETIRED":"0.0000000000","INVOICEDAYOFWEEK":"5.0000000000",     "ID":"1234567.0000000000","BEANVERSION":"69.0000000000",     "ACCOUNTTYPE":"1.0000000000","ORGANIZATIONTYPEDENORM":null,     "HIDDENTACCOUNTCONTAINERID":"4321987.0000000000",     "NEWPOLICYPAYMENTDISTRIBUTABLE":"1","ACCOUNTNUMBER":"000-000-000-00",     "PAYMENTMETHOD":"12345.0000000000","INVOICEDELIVERYTYPE":"98765.0000000000",     "DISTRIBUTIONLIMITTYPE":"3.0000000000","CLOSEDATE":null,     "FIRSTTWICEPERMTHINVOICEDOM":"1.0000000000","HELDFORINVOICESENDING":"0",     "FEINDENORM":null,"COLLECTING":"0","ACCOUNTNUMBERDENORM":"000-000-000-00",     "CHARGEHELD":"0","PUBLICID":"xx:1234346"}for key in j:    if j[key] is not None:        if re.match("^\d+?\.\d+?$", j[key]):            j[key] = float(j[key])我null = None在这里用来处理出现在 JSON 中的“null”。但是您可以在此处用您正在阅读的每个 CSV 行替换 'j',然后使用它来更新该行,然后用浮点数替换字符串将其写回。如果您可以将任何数字字符串转换为浮点数,那么您可以跳过正则表达式(re.match()命令)并将其替换为j[key].isnumeric(),如果它适用于您的 Python 版本。编辑:我不认为 Python 中的浮点数以您可能认为的方式处理“精度”。它可能看起来像是2.0000000000被“截断”为2.0,但我认为这更多是格式和显示问题,而不是丢失信息。考虑以下示例:>>> float(2.0000000000)2.0>>> float(2.00000000001)2.00000000001>>> float(1.00) == float(1.000000000)True>>> float(3.141) == float(3.140999999)False>>> float(3.141) == float(3.1409999999999999)True>>> print('%.10f' % 3.14)3.1400000000虽然有可能让 JSON 包含这些零,但在这种情况下,它归结为将数字视为字符串,即格式化的字符串。
随时随地看视频慕课网APP

相关分类

Python
我要回答