首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将JSON转换为CSV?

如何将JSON转换为CSV?
EN

Stack Overflow用户
提问于 2009-12-09 12:06:38
回答 23查看 671.8K关注 0票数 245

我有一个要转换为CSV文件的JSON文件。我如何使用Python做到这一点?

我试过了:

代码语言:javascript
复制
import json
import csv

f = open('data.json')
data = json.load(f)
f.close()

f = open('data.csv')
csv_file = csv.writer(f)
for item in data:
    csv_file.writerow(item)

f.close()

然而,它并没有起作用。我正在使用Django,我收到的错误是:

代码语言:javascript
复制
`file' object has no attribute 'writerow'`

然后,我尝试了以下方法:

代码语言:javascript
复制
import json
import csv

f = open('data.json')
data = json.load(f)
f.close()

f = open('data.csv')
csv_file = csv.writer(f)
for item in data:
    f.writerow(item)  # ← changed

f.close()

然后我得到了这个错误:

代码语言:javascript
复制
`sequence expected`

示例json文件:

代码语言:javascript
复制
[{
        "pk": 22,
        "model": "auth.permission",
        "fields": {
            "codename": "add_logentry",
            "name": "Can add log entry",
            "content_type": 8
        }
    }, {
        "pk": 23,
        "model": "auth.permission",
        "fields": {
            "codename": "change_logentry",
            "name": "Can change log entry",
            "content_type": 8
        }
    }, {
        "pk": 24,
        "model": "auth.permission",
        "fields": {
            "codename": "delete_logentry",
            "name": "Can delete log entry",
            "content_type": 8
        }
    }, {
        "pk": 4,
        "model": "auth.permission",
        "fields": {
            "codename": "add_group",
            "name": "Can add group",
            "content_type": 2
        }
    }, {
        "pk": 10,
        "model": "auth.permission",
        "fields": {
            "codename": "add_message",
            "name": "Can add message",
            "content_type": 4
        }
    }
]
EN

回答 23

Stack Overflow用户

发布于 2009-12-09 14:56:38

首先,您的JSON具有嵌套对象,因此它通常不能直接转换为CSV。您需要将其更改为如下所示:

代码语言:javascript
复制
{
    "pk": 22,
    "model": "auth.permission",
    "codename": "add_logentry",
    "content_type": 8,
    "name": "Can add log entry"
},
......]

下面是我用来生成CSV的代码:

代码语言:javascript
复制
import csv
import json

x = """[
    {
        "pk": 22,
        "model": "auth.permission",
        "fields": {
            "codename": "add_logentry",
            "name": "Can add log entry",
            "content_type": 8
        }
    },
    {
        "pk": 23,
        "model": "auth.permission",
        "fields": {
            "codename": "change_logentry",
            "name": "Can change log entry",
            "content_type": 8
        }
    },
    {
        "pk": 24,
        "model": "auth.permission",
        "fields": {
            "codename": "delete_logentry",
            "name": "Can delete log entry",
            "content_type": 8
        }
    }
]"""

x = json.loads(x)

f = csv.writer(open("test.csv", "wb+"))

# Write CSV Header, If you dont need that, remove this line
f.writerow(["pk", "model", "codename", "name", "content_type"])

for x in x:
    f.writerow([x["pk"],
                x["model"],
                x["fields"]["codename"],
                x["fields"]["name"],
                x["fields"]["content_type"]])

您将得到如下输出:

代码语言:javascript
复制
pk,model,codename,name,content_type
22,auth.permission,add_logentry,Can add log entry,8
23,auth.permission,change_logentry,Can change log entry,8
24,auth.permission,delete_logentry,Can delete log entry,8
票数 145
EN

Stack Overflow用户

发布于 2015-01-31 07:11:28

我假设您的JSON文件将解码为一个字典列表。首先,我们需要一个平面化JSON对象的函数:

代码语言:javascript
复制
def flattenjson(b, delim):
    val = {}
    for i in b.keys():
        if isinstance(b[i], dict):
            get = flattenjson(b[i], delim)
            for j in get.keys():
                val[i + delim + j] = get[j]
        else:
            val[i] = b[i]
            
    return val

在JSON对象上运行此代码片段的结果:

代码语言:javascript
复制
flattenjson({
    "pk": 22, 
    "model": "auth.permission", 
    "fields": {
      "codename": "add_message", 
      "name": "Can add message", 
      "content_type": 8
    }
  }, "__")

代码语言:javascript
复制
{
    "pk": 22, 
    "model": "auth.permission", 
    "fields__codename": "add_message", 
    "fields__name": "Can add message", 
    "fields__content_type": 8
}

将此函数应用于JSON对象的输入数组中的每个dict之后:

代码语言:javascript
复制
input = map(lambda x: flattenjson( x, "__" ), input)

并查找相关的列名:

代码语言:javascript
复制
columns = [x for row in input for x in row.keys()]
columns = list(set(columns))

通过csv模块运行它并不难:

代码语言:javascript
复制
with open(fname, 'wb') as out_file:
    csv_w = csv.writer(out_file)
    csv_w.writerow(columns)

    for i_r in input:
        csv_w.writerow(map(lambda x: i_r.get(x, ""), columns))

我希望这能帮到你!

票数 108
EN

Stack Overflow用户

发布于 2009-12-09 12:27:25

JSON可以表示各种各样的数据结构-- JS“对象”大致类似于Python dict (带有字符串键),JS“数组”大致类似于Python列表,只要最后的“叶”元素是数字或字符串,就可以嵌套它们。

CSV本质上只能表示2-D表格--可选地,具有第一行“标题”,即“列名”,这可以使表格可解释为字典列表,而不是正常解释的列表列表(同样,“叶”元素可以是数字或字符串)。

因此,在一般情况下,您不能将任意JSON结构转换为CSV。在一些特殊情况下,您可以(不再嵌套的数组数组;具有完全相同键的对象数组)。哪种特殊情况(如果有)适用于您的问题?解决方案的细节取决于您有哪种特殊情况。考虑到令人惊讶的事实,您甚至没有提到哪一个适用,我怀疑您可能没有考虑到约束,这两种可用的情况实际上都不适用,并且您的问题无法解决。但是请一定要澄清!

票数 39
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1871524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档