【问题标题】:How to convert from csv to nested json dictionary ( A beginner )如何从 csv 转换为嵌套的 json 字典(初学者)
【发布时间】:2021-10-23 17:26:02
【问题描述】:

我的结果:

[
    {
        "FIRST NAME": "JOHN",
        "PRY SCHOOL": "OLIVETTE",
        "HIGH SCHOOL": "BAPTIST",
        "VEHICLEMAKE ": "TOYOTA",
        "VEHICLE COL": "BLACK",
        "TV MAKE": "SAMSUNG"
    },
    {
        "FIRST NAME": "KOFI",
        "PRY SCHOOL": "ACADAMY", 
        "HIGH SCHOOL": "MAYFLOWER",
        "VEHICLEMAKE ": "HONDA",
        "VEHICLE COL": "YELLOW",
        "TV MAKE": "TECHWOOD"
    },
    {
        "FIRST NAME": "BISI",
        "PRY SCHOOL": "IGBOBI",
        "HIGH SCHOOL": "ANGUS",
        "VEHICLEMAKE ": "HYUNDAI",
        "VEHICLE COL": "BLUE",
        "TV MAKE": "THERMOC"
    }
]

预期结果:

[
    {
        "FIRST NAME": "JOHN",
        "SCHOOL": {
            "primary": "OLIVETTE",
            "HIGH SCHOOL": "BAPTIST"
        },
        "VEHICLE": {
            "MAKE": "TOYOTA",
            "COL": "BLACK"
        },
        "TV MAKE": "SAMSUNG"
    },
    {
        "FIRST NAME": "KOFI",
        "SCHOOL": {
            "primary": "ACADAMY",
            "HIGH SCHOOL": "MAYFLOWER"
        },
        "VEHICLE": {
            "MAKE": "HONDA",
            "COL": "YELLOW"
        },
        "TV MAKE": "TECHWOOD"
    },
    {
        "FIRST NAME": "BISI",
        "SCHOOL": {
            "primary": "IGBOBI",
            "HIGH SCHOOL": "ANGUS"
        },
        "VEHICLE": {
            "MAKE": "HYUNDAI",
            "COL": "BLUE"
        },
        "TV MAKE": "THERMO"
    }
]

我的代码:

import csv
import json

filenames = 'csvfilepath.csv'
my_dic = []

with open(filenames, encoding='utf-8') as csv_file:
     csv_reader = csv.DictReader(csv_file)

     for row in csv_reader:
         my_dic.append(row)

with open('jasonfilepath.json', 'w', encoding='utf-8') as file_object:
    json.dump(my_dic, file_object ,indent = 4)

我的数据:

firstname  PRY SCHOOL HIGH SCHOOL VEHICLEMAKE VEHICLECOL  TVMAKE
JOHN       OLIVETTE   BAPTIST     TOYOTA      BLACK       SAMSUNG
KOFI       ACADAMY    MAYFLOWER    HONDA      YELLOW      TECHWOOD
BISI       IGBOBI     ANGUS        HYUNDAI    BLUE         THERMO

注意:行数超过 1000 行

我想确保学校(包括小学和中学)和车辆(品牌和颜色)的嵌套结构

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 您的输入 CSV 数据文件选项卡是否分开?

标签: python json dictionary


【解决方案1】:

DictReader 无法读取嵌套数据,需要手动构造所需结构的字典。对于这种情况,我会使用简单的csv.reader

代码:

import csv
import json

with open(r"csvfilepath.csv", newline="") as inp_f, \
        open(r"jsonfilepath.json", "w") as out_f:
    reader = csv.reader(inp_f, delimiter="\t")
    next(reader)  # skip header
    my_dic = []
    for row in reader:
        if len(row) >= 6:  # skip rows which missing columns
            my_dic.append({
                "FIRST NAME": row[0],
                "SCHOOL": {
                    "primary": row[1],
                    "HIGH SCHOOL": row[2]
                },
                "VEHICLE": {
                    "MAKE": row[3],
                    "COL": row[4]
                },
                "TV MAKE": row[5]
            })
    if my_dic:  # if my_dic is not empty
        json.dump(my_dic, out_f, indent=4)

【讨论】:

  • 请我解释一下为什么当 len(row)>=6 被删除时此代码将不起作用我试图删除它并且代码失败。我需要解释以便更好地了解正在发生的事情。
  • @AbdRaheem,它检查行中是否至少有 6 列。
【解决方案2】:

类似于以下内容(您确定“TV MAKE”的位置吗?)

import json
data = [ { "FIRST NAME": "JOHN", "PRY SCHOOL": "OLIVETTE", "HIGH SCHOOL": "BAPTIST", "VEHICLEMAKE ": "TOYOTA", "VEHICLE COL": "BLACK", "TV MAKE": "SAMSUNG" }, { "FIRST NAME": "KOFI", "PRY SCHOOL": "ACADAMY", "HIGH SCHOOL": "MAYFLOWER", "VEHICLEMAKE ": "HONDA", "VEHICLE COL": "YELLOW", "TV MAKE": "TECHWOOD" }, { "FIRST NAME": "BISI", "PRY SCHOOL": "IGBOBI", "HIGH SCHOOL": "ANGUS", "VEHICLEMAKE ": "HYUNDAI", "VEHICLE COL": "BLUE", "TV MAKE": "THERMOC" } ]


new = [{'SCHOOL':{'PRIMARY':d['PRY SCHOOL'],'HIGH SCHOOL':d['HIGH SCHOOL']},'VEHICLE':{'MAKE':d['VEHICLEMAKE '],'COL':d['VEHICLE COL']},'FIRST NAME':d['FIRST NAME'],'TV MAKE':d['TV MAKE']} for d in data]

print(json.dumps(new,indent=4))

输出

[
    {
        "SCHOOL": {
            "PRIMARY": "OLIVETTE",
            "HIGH SCHOOL": "BAPTIST"
        },
        "VEHICLE": {
            "MAKE": "TOYOTA",
            "COL": "BLACK"
        },
        "FIRST NAME": "JOHN",
        "TV MAKE": "SAMSUNG"
    },
    {
        "SCHOOL": {
            "PRIMARY": "ACADAMY",
            "HIGH SCHOOL": "MAYFLOWER"
        },
        "VEHICLE": {
            "MAKE": "HONDA",
            "COL": "YELLOW"
        },
        "FIRST NAME": "KOFI",
        "TV MAKE": "TECHWOOD"
    },
    {
        "SCHOOL": {
            "PRIMARY": "IGBOBI",
            "HIGH SCHOOL": "ANGUS"
        },
        "VEHICLE": {
            "MAKE": "HYUNDAI",
            "COL": "BLUE"
        },
        "FIRST NAME": "BISI",
        "TV MAKE": "THERMOC"
    }
]

【讨论】:

  • 不,谢谢。我已经编辑了我的问题。我想在学校(包括小学和中学)和车辆(包括车辆品牌和颜色)有一个嵌套结构,行数超过1000行,所以我们不能使用上面的方法。
  • 电视品牌和名字没有嵌套。
  • @AbdRaheem 查看输出。这是您正在寻找的确切输出。你能解释一下缺少什么吗?
【解决方案3】:

假设制表符分隔输入文件,您可以在读取输入文件时通过稍微修改逻辑来构建嵌套:

with open(filenames, encoding='utf-8') as csv_file:
     csv_reader = csv.DictReader(csv_file, delimiter="\t")
     for row in csv_reader:
         my_dic.append({"FIRST NAME": row['firstname'],
                        "SCHOOL" : { "PRIMARY": row['PRY SCHOOL'],
                                     "HIGH SCHOOL" : row['HIGH SCHOOL']},
                        "VEHICLE" : { "MAKE": row['VEHICLEMAKE'],
                                      "COL": row['VEHICLECOL']},
                        "TV MAKE" : row["TVMAKE"]})

【讨论】:

    猜你喜欢
    • 2014-09-16
    • 2015-08-25
    • 2021-10-21
    • 2018-12-27
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多